Einzelnen Beitrag anzeigen

Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#18

Re: Was ist ein Objekt ?

  Alt 28. Jul 2008, 23:12
Worin liegt der primäre Unterschied zwischen einem Ottomotor und einer Gasturbine ? Das eine ist die Weiterentwicklung des Anderen. Und Gleiches trifft auf Objekte und Klassen zu, wobei schon die Namensgebung im Grunde falsch ist.

Klassen sind mit Objekten garnicht vergleichbar da eine Klasse eher wie ein Template die allozierbaren Objekte = Instanzen umschreiben. Wir erzuegen aus einer Klasse, also einem OOP Typ, durch Allozierung im Heap oder meinetwegen auch Stack, eine Instanz. Diese Instanz bezeichnet man auch als ein Objekt.

Eine Klasse ist also eine Datentyp-Deklaration die das Verhalten und Aussehen ihrer zur Laiufzeit erstellbaren Instanzen = Objekte definiert.

Evolutionär betrachtet waren die Delphi, eg. Borland Pascal 5, Objekte nur die Vorstufe zu Klassen. Später wurden die "Klassen" als solches eingeführt aber im Grunde könnten die alten Delphi Objekte alles das unterstützen was heutige Klassen können. Eine Klasse in Delphi unterscheidet sich auf 3 Arten von Objekten in Delphi

1.) die Art und Weise wie deren Klasse im Codesegment gespeichert wird. Eine Klasse ist ein Record im Codesegement indem per RTTI=Run Time Type Information alles was diese Klasse kann gespeichert wurde. Also die virtuellen und dynamischen Methoden in der VMT und DMT, alle publisched Eigenschaften und Ereignismethoden samt Paramater dieser Methoden, alle implementierten Intaerfaces usw. usw.
Die alten Objekte in Delphi stellen eine Untermenge dieser Klassenstruktur dar, das erkennt man auch sehr einfach im Aufbau dieses Klasenrecords. Der Klassenzeiger, also TObject.ClassType^ = PPonter(Self)^^ zeigt mitten in diesen Klassenrecord im Codesegment exakt an den Begin der VMT=Virtual Method Table. Nun die alten Objekte und deren Klassenrecord begint exakt mit einem Zeiger auf diese VMT. Einige der nachfolgenden Felder innerhalb dieses Klassenrecords sind zwischen den alten Objekten und neuen Klassen identisch.

2.) Die Möglichkeit polymorphe Klassen zu benutzen. Das ist nicht identisch mit der Polymorphie innerhalb der Klassenhierarchie sondern meint das man mit variablen/dynamsichen Klassen arbeiten kann und somit dynamisch den Typ der Klasse nach der man eine Instanz/Objekt allozieren/initialkiseiren möchte.

3.) eine Klasse ist nur eine syntaktische Unterscheidung zwischen der Deklaration eines OO-Types und der daraus allozierbaren Instanzen/Objekte zur Laufzeit. Damit hat Borland das OOP Konzept nur syntaktisch "aufgeräumt" im Vergleich zu den "alten Objekten".

Sogesehen besteht der Hauptunterschied zwischen Klassen und alten Objekten in Borland Delphi nur darin das das eine veraltet ist und das Andere die konsequente Weiterentwicklung der Objekte hin zu Klassen darstellt.

Objekte konnte man von Anfang an auch im Heap dynamisch allozieren und man benutzte dazu auch Konstruktoren und Destruktoren (allerdings manuell deklariert und aufgerufen, gehörte damals zum guten Ton seine Objekte mit virtuellen Initializations-Methoden zu versehen, genannt Konstruktoren). Die vergleichbaren Destruktoren/Konstruktoren in Klassen sind im Grunde normale Klassenmethoden, also Methoden deren impliziter Parameter Self nicht auf die Instanz einer Klasse zeigt sondern auf die Klassendefinition selber, also ein Zeiger in das Codsegment in der der Compiler alles wichtige zu dieser Klasse abgespeichert hat.

Der Unterschied zwischen Konstruktoren/Destruktoren im Vergleich zu normalen Klassenmethoden besteht darin das in der VMT/DMT der Klasse keine eigenen Slots eingerichtet werden, sondern das beide Methoden innerhalb der Klassenstruktur an festem Offset ihren Zeiger auf die implementierende Methode besitzen. Das ist aber eher ein Relikt bei der Weiterentwicklung durch Borland und nicht das allgemeingültige Konzept wie man Klassen speichert. Viel öfters werden diese Spezialmethoden in anderen Sprachen genauso behandelt wie ganz normale virtuelle/dynamische Klassenmethoden. Dies zeigt sich auch darin das man in neueren Delphi Version auch diese Konstruktoren/Destruktoren überladen kann, aber das ist ein anderes Thema.

Fazit: der Unterschied zwischen Objekten und Klassen besteht darin das man Objekte nicht mehr benutzen sollte da sie durch Klassen ersetzt wurden und diese mehr können. Und zweitens räumt der syntaktische Aufbau bei einer Definition und Benutzung einer Klasse mit den Verständnisschwierigkeiten der alten syntaktischen Schreibweise der Objekte auf. Das ist übrigens der wichtigste Grund warum Klassen mächtiger sind, sie sind leichter für den Programmierer verständlich.

Das OOP Konzept der Trennnung von Klassen, darauf aufbauend Klassenhierarchien, von deren zur Laufzeit allozierten Instanzen, also Objekten, ist schon mit Borland Pascal bekannt. Aber die explizite syntaktische Trennung beider erst mit der Einführung von Klassen, also dem Bezeichner class und class of. Grundsätzlich konnte man auch mit den alten Objketen alles das machen was heutige Klassen können aber das Verständnis der Entwickler scheiterte an dem Punkt das es syntaktisch keine klare Trennung gab.

Ich habe mit den alten Objekten schon zu Zeiten von Turbo Vision unter DOS mit all den Features gearbeitet die mit heutigen Klassen so möglich sind. Nur das man heutzutage syntaktisch sauberer OO-programmiert und mit den alten Objekten eben teilweise tricksen musste. Letzendlich ist die Unterstützung des Compilers verantwortlich das man mit den alten Objekten nicht so arbeiten kann wie mit den neuen Klassen, technisch gesehen ist beides das Gleiche, ein Record aus Felder als Laufzeit Objekt der irgendwo ein Datenfeld besitzt der auf eine Record der Klasse zeigt und dieser Klassenrecord ist fix irgendwo gespeichert und enthält alles was diese Klasse so kann, sprich VMT/DMT/IntfTable/RTTI/Porperties/Events/Classname/Parentclass usw.

Auch Instanzen heutiger Klassen kann man auf den Stack allozieren, grundsätzlich kann man diese in jeder Art von Speicher allozieren, gleiches gilt für Objekte.
Und wenn der Compiler es unterstützen würde so könnte dieser auch Instanzen alloziert im Stack oder Heap autom. nach Verlassen der Scope wieder freigeben. All dies sind keine Merkmale von Klassen/Objekten oder OOP im speziellen sondern nur Merkmale inwieweit der Compiler nahtlos die OOP unterstützt.
Die alleinige Allozerbarkeit von Objekten in einem Stack widerspricht der OOP und ist unlogisch, da so die Lebenszeit einer jeden Objektinstanz immer nur lokal zur Scope der Funktion die den Stack einrichtet, beschränkt wäre. Somit musste man von Anfang an in der Lage sein Instanzen auch im Heap zu allozieren, gerade auch bei den alten Objekten, damit deren Lebenszeit unabhängig eines Stacks ist. Die Allokation von Objekten auf dem Stack ist auch keineswegs ein Vorteil. Nur weil der Compiler die implizite Freigabe solcher Objekte mit der Freigabe des lokalen Stacks uterstützt heist dies nicht das dies nun ein gewolltes Feature der Borland Entwickler war, eher ein notwendiges Übel und quasi eine Schallmauer die nur durch Allokationen im Heap durchbrochen werden konnte. Das hat auch nichts mit Garbarge Collection zu tuen, es sei denn man gibt dem Kinde "Stack" und dessen Funktionsweise lokale Resourcen beim Verlassen einer Procedure autom. wieder freigeben zu können, diesen Namen. Übrigens ebenfalls eine Erfindung unseres geehrten N.Wirths, der diese Form der Stackbehandlung als erstes in Pascal eingebaut hatte.

Zitat:
Ist aber eigentlich mächtiger als Klassen. Objects ähneln C++-Klassen: Du kannst sie sowohl auf dem Stack als auch auf dem Heap anlegen, es gibt Vererbung, virtuelle Methoden...
Nicht im entferntesten mächtiger, wenn man Klassen und Objekte überhaupt miteinander vergleichen kann. Klassen sind keine Objekte sondern eine Arbeitsvorlage für Objekte. Aus einer Klasse kann man zur Laufzeit sehr viele Instanzen/Objekte erzeugen, alle mit gleichen Klasseneigenschaften aber denoch individuell über ihre unterschiedlichen Feldinhalte.

Die Allozierbarkeit von Objekten aus Klassen ist nicht nur auf den Heap beschränkt. Überschreibt man für eine Klasse die .InitInstance und .FreeInstance Methoden dan kann man die Instazen/Objekte dieser Klasse in jedem beliebigen Speichermedium allozieren, also auch im Stack. Nur ist dies eben kein Vorteil auch wenn es C++ so macht was ja nur eine komfortablere Makroassemblersprache darstellt und keine echte Hochsprache da sind wir Delphianer doch wohl einer Meinung oder ?
[edit]
und wer sagt das Pascal Objekte denen im C++ ähneln, falsch, C++ Objekte ähneln denen vom Pascal... denn das hatte das früher
[/edit]

Gruß Hagen
  Mit Zitat antworten Zitat