Autor |
Beitrag |
Hein Blöd
      
Beiträge: 51
|
Verfasst: Sa 03.04.04 14:49
Ich hab mir 20000 Bücher und Faqs durchgelesen, aber ich blicke immer noch nicht bei inherited durch. Es wird irgendwie immer als selbstverständlich angesehen. Ich hab ein dickes Buch, so an die 1000 Seiten, das sich mit jedem Scheiß beschäftigt. Da werden die unwichtigsten Sachen deart in die Länge gezogen, daß man fast den Spaß am lesen verliert. Anscheinend wurde der Autor nach Seiten bezahlt, denn er ist in der Lage die einfachste Sache der Welt über zehn Seiten auszudehnen. Dann kam er irgendwann an inherited und handelte das mit zwei Sätzen ab. Eben das ist wichtig und das muß sein. Aber auch andere Bücher sind mir keine große Hilfe. Da wird irgendwie schon immer davon ausgegangen, daß man es bescheidweiß. Auch wenn es ein Anfängebuch ist.
Natürlich bleibt davon etwas kleben, aber es ist nicht so, und das ist jetzt sehr wichtig, daß es ohne zu überlegen nutzen könnte. Es ist nicht die Selbstverständlichkeit da mit der ich z.B. andere Dinge des Delphi behandele. Die Regel, daß inherited bei Constructor vorne und bei Dectructor hinten sein soll, die kenne ich. Aber warum? Ich weiß auch, daß inherited eine art Schlüssel ist mit der ich bei Klassenerstellung irgendwas mache. Aber es fehlt mit der Aha Effekt. Ich will Klassen erstellen, aber ohne das Verständnis von inherited werde ich es nicht so richtig kappieren. Wer kann mit den Aha Effekt verpassen?
|
|
raziel
      
Beiträge: 2453
Arch Linux
JS (WebStorm), C#, C++/CLI, C++ (VS2013)
|
Verfasst: Sa 03.04.04 15:24
im prinzip wird durch inherited die funktion des vorgängers aufgerufen.
Wenn man also von TButton TMeinButton ableitet
Delphi-Quelltext 1:
| TMeinButton = class(TButton) |
wird durch das inherited hier
Delphi-Quelltext 1: 2: 3: 4: 5:
| constructor TMeinButton.Create(AOwner: TComponent); begin inherited create(AOwner); end; |
erst das Create von TButton abgearbeitet. So habs jedenfalls ich verstanden...
deswegen muss bei Destroy auch erst der eigene Code stehen und am Ende erst inherited.
raziel
_________________ JSXGraph
|
|
Andy DBase
      
Beiträge: 42
win XP Home, win 98SE
D7 Prof
|
Verfasst: Sa 03.04.04 15:50
mir hat ein Blick in's Wörterbuch geholfen, probier's doch auch mal... 
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Sa 03.04.04 18:28
to inherited heißt vererben - und genau das bewirkt inherited auch... durch inherited wird die entsprechende Methode der Basisklasse aufgerufen..
Der Sinn warum beim Konstruktor inherited als erstes, und beim Destruktor als letztes aufgerufen werden sollte ist einfach:
ein Aufruf von "inherited Create" sorgt dafür, dass der Konstruktor der Basis-Klasse aufgerufen wird. Das ist wichtig, da ja im Konstruktor diverse Felder initialisiert werden und eventuell benötigte Objekte erzeugt werden. Sofern man eines dieser Felder der Basis-Klasse in seinem eigenen Konstruktor braucht wäre es doch etwas blöd wenn es zu diesem Zeitpunkt noch nicht initialisiert wäre..  Und beim Destruktor ist es eben genau umgekehrt..!
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
raziel
      
Beiträge: 2453
Arch Linux
JS (WebStorm), C#, C++/CLI, C++ (VS2013)
|
Verfasst: Sa 03.04.04 19:11
Motzi hat folgendes geschrieben: | to inherited heißt vererben |
[klugscheiß]
1. to inherited gibts nicht. nur to inherit
2. es heißt erben, nicht vererben.
[/klugscheiß]

_________________ JSXGraph
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: So 04.04.04 12:01
raziel hat folgendes geschrieben: | 1. to inherited gibts nicht. nur to inherit |
Hoppla.. mein ich ja.. 
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
Hein Blöd 
      
Beiträge: 51
|
Verfasst: So 04.04.04 14:36
Vielen Dank für die Hilfe, aber der Aha Effekt ist immer noch nicht da. Zwar ist die Bemerkung Inherited = Erben gut und sagt aus was damit gemeint ist, aber so 100%'ig weiss ich immer noch nicht wie das geht. Hier eine Frage die ich vor paar Wochen gestellt habe: www.delphiforum.de/viewtopic.php?p=129103
Hier die Kurzfassung. Auf die Frage ob das korrekt ist
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| constructor TListen.Create; begin Liste1 := TStringList.Create; Liste2 := TStringList.Create; Liste3 := TStringList.Create; end;
destructor TListen.Free; begin Liste1.Free; Liste2.Free; Liste3.Free; end; |
meinte KidPaddle, dass das besser ist
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| constructor TListen.Create; begin inherited Create;
fListe1 := TStringList.Create; fListe2 := TStringList.Create; fListe3 := TStringList.Create; end;
destructor TListen.Destroy; begin FreeAndNil(fListe1); FreeAndNil(fListe2); FreeAndNil(fListe3);
inherited Destroy; end; |
Ignorieren wir mal FreeAndNil und die etwas andere Variablenamen, aber warum ist es besser hier inherited zu nehmen. Es funktioniert auch ohne.
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: So 04.04.04 14:45
Zwei Sachen...
1) Free ist kein Destruktor sondern nur eine Methode die folgendermaßen ausschaut:
Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure TObject.Free; begin if Self <> nil then Destroy; end; |
Free ruft also intern Destroy auf falls der Self-Pointer ungleich nil ist.
Deswegen überschreibt man auch immer Destroy und nicht Free..!
2) inherited ruft man immer auf, damit auch die Methode der Basisklasse ausgeführt wird. Gerade beim Konstruktor als auch beim Destruktor ist das besonders wichtig, damit auch die Basisklasse diverse Initialisierungen und Aufräumarbeiten durchführen kann.
Nachdem deine Klasse aber von TObject abgeleitet ist ist es egal ob du inherited aufrufst, da sowohl der Konstruktor Create als auch der Destruktor Destroy von TObject eigentlich nur eine Dummy-Dasein fristen, da sie beide einen leeren Funktions-Rumpf haben:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| constructor TObject.Create; begin end;
destructor TObject.Destroy; begin end; |
In (fast) allen anderen Fällen ist es aber äußerst wichtig inherited aufzurufen..!
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
Phantom1
      
Beiträge: 390
|
Verfasst: So 04.04.04 14:58
Schau dir mal folgendes Beispiel genau an:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
| type TBasisObj = class(TObject) public constructor Create; destructor Destroy; override; end;
TNeuObj = class(TBasisObj) public constructor Create; destructor Destroy; override; end;
constructor TBasisObj.Create; begin inherited Create; end;
destructor TBasisObj.Destroy; begin inherited Destroy; end;
constructor TNeuObj.Create; begin inherited Create; end;
destructor TNeuObj.Destroy; begin inherited Destroy; end; |
Man kann im übrigen wirklich den Aufruf von Inherited bei einer direkt von TObject-Abgeleiteten klasse weglassen, weil der Constructor und Destructor in der TObject-Klasse leer ist. Man sollte es aber trotzdem machen, wegen der übersichtlichkeit und evtl verwirrung ^^
|
|
KidPaddle
      
Beiträge: 351
WinXP,Linux
D7 Prof, XE7
|
Verfasst: So 04.04.04 15:10
Die Bedeutung von inherited ist schon erklärt worden. Jedes Objekt kapselt Daten, die es für die Verabreitung in irgendeiner Art und Weise benötigt. Wenn Du ein Basisobjekt hast, welches ein Array verwaltet, dann wird dieses Array z. B. im Constructor erstellt und im Destructor wieder freigegeben. Weitere Methoden des Objektes greifen auf das im Constructor reservierte Array zu. Diese erwarten, das das Array richtig initialisiert wurde.
Du leitest ein neues Objekt von dem Basisobjekt ab. Wenn Du nicht den Constructor des Vorgänger mit inherited aufrufst, dann wird das Array nicht reserviert und die Mehtoden, die dieses Array manipulieren, erzeugen Speicherzugriffsfehler. Machst Du den Aufruf nicht im Destructor, bleibt ein Memory Leak, das heist, nicht freigegebener Speicher, übrig und das kann zum Absturz der Anwendung oder mehr führen, wenn dieses Objekt sehr häufig verwendet wird. Normalerweise gibt Delphi den Speicher beim beenden des Programmes frei, aber halt erst beim beenden und nicht während des laufenden Programmes.
Dein Objekt wurde direkt von TObjekt abgeleitet. Der Constructor und Destructor von TObjekt ist aber leer und daher gibt es beim weglassen von inherited keine Probleme. Das ist aber eine Ausnahme, wenn man mit Objekten arbeitet. Damit man nicht immer wieder an die Ausnahmen denken muss, wenn man den Quelltext sich ansieht, setzt man den Aufruf einfach rein, schaden tut er nicht und man gewöhnt sich gleich an, den Aufruf den Constructor/Destructors nicht zu vergessen.
Ich hoffe, ich konnte es Dir verdeutlichen.
Gruß
KidPaddle
|
|
Hein Blöd 
      
Beiträge: 51
|
Verfasst: Sa 03.07.04 18:17
Ich versuche mich noch mal mit den Thema und bringe es wieder nach vorne.
Ich hab alle Hinweise beachtet und unendlich viele Beispiele gemacht. Aber egal was ich mache, nie kriege ich Probleme wenn ich inherited weglasse. Ich hab Klassen erstellt, die abgeleitet wurden. Die hab ich wieder abgeleitet und wieder. Zwischendurch hab ich Objekte initialisiert und in der abgeleietetn Klasse angewendet. Nie hatte ich Probleme es ohne inherited zu machen. Vielleicht ist das Ganze nicht so kompliziert wie ich mir das vorstelle. Aber jedes mal wenn ich glaube es verstanden zu haben kommt etwas was mich wieder durcheinanderbringt.
Ich gehöre leider zu den Leuten die nicht weiter machen können wenn sie ein Problem haben. Zur Zeit verstehe ich die Sache mit inherited nicht. Daraus follgt, daß das ganze Klassen Thema liegen lasse. Ich kann einfach nicht etwas hinnehmen. Vielleicht kann einer mir ein Beispiel fabrizieren das wirklich knallt, wenn ich kein inherited nehme. Irgendwie hab ich den Aha Effekt nicht und egal was ich machen er kommt nicht. Ich könnte einfach inherited einbauen, aber wenn ich es nicht verstehe, dann wiederstrebt es in mir es zu machen.
Ich will nicht beachaupten, daß ich das was bisher geschrieben wurde nicht verstanden habe, aber ein *ach so ist das* kommt nicht zu stande.
Ich verstehe, daß meine Klasse die Eigenschaften der alten klasse erbt. Aber egal was für ein Beispiel ich gemacht habe, es klappte auch ohne inherited.
|
|
mstuebner
      
Beiträge: 132
Win2000, XP
D7
|
Verfasst: Sa 03.07.04 19:35
Hein Blöd hat folgendes geschrieben: | Zur Zeit verstehe ich die Sache mit inherited nicht. |
Ich befürchte, dass man es nicht noch besser und einfacher beschreiben kann, als dies bereits geschehen ist.
Hein Blöd hat folgendes geschrieben: | Vielleicht kann einer mir ein Beispiel fabrizieren das wirklich knallt, wenn ich kein inherited nehme. |
Dann lies den Thread noch einmal. Genau diese Beispiele sind hier aufgezeigt. Wenn auch schon in jedem Beitrag geschrieben, wenn ohne inherited wird die gleichnamige Methode der Vorgängerklasse nicht aufgerufen und dadurch evtl. Initialisierungen nicht durchgeführt. Nicht mehr, nicht weniger, nichts anderes.
Hein Blöd hat folgendes geschrieben: | Ich will nicht beachaupten, daß ich das was bisher geschrieben wurde nicht verstanden habe, aber ein *ach so ist das* kommt nicht zu stande. |
Kannst Du mal ein Beispiel geben WANN es bei Dir "aha so ist das" macht?
_________________ mfg Matthias
|
|
dmx
      
Beiträge: 19
Gentoo Linux, Win XP Pro
D6 Prof, K3 Open, Freepascal
|
Verfasst: Sa 03.07.04 21:41
hallo zusammen,
okay, dann versuch ich auch mal es zu erklären. vielleicht mal ein beispiel, das nichts mit konstruktoren und destruktoren zu tun hat.
etwas verallgemeinert gesprochen hilft inherited vor allem dann, wenn wir keine konkreten gegenstände in klassen abstrahiert abbilden, sondern stattdessen, wenn wir abläufe oder vorgänge "objektivieren". soviel nur zur theorie der objektorientieren programmierung.
stellen wir uns einfach mal vor, wir wollen eine kleine klassenhierachie erstellen, um einen kauf abzubilden.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| TVorgang = class public procedure Ausführen; virtual; end;
TKaufVorgang = class(TVorgang) public procedure Ausführen; override; end; |
virtual in der ersten klasse macht diese procedure grob gesprochen überladbar. dh. in jedem nachfolger (KaufVorgang) kann eine procedure genauso heißen, nur muss dann in diesem nachfahren (TKaufVorgang) noch das schlüsselwort override angegeben werden.
implementieren wir nun:
Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure TVorgang.Ausführen; begin FasseEntschluss; BereiteAllesVor; end; |
um einen vorgang abschließen zu können benötogen wir logischerweise erst mal den entschluss und müssen dann alles vorbereiten.
wenn wir nun etwas konkreter werden und einen nachfahren von TVorgang implementieren, zb. TKaufVorgang, dann schaut des erstmal so aus:
Delphi-Quelltext 1: 2: 3: 4:
| procedure TKaufVorgang.Ausführen; begin Kaufe; end; |
nun, das ist eigentlich klar. aber der vorgang ist so noch nicht komplett, denn auch zum kaufen gehören ja schließlich der entschluss und die vorbereitung (mehr oder weniger). klar, wir könnten hingehen und folgendes machen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| procedure TKaufVorgang.Ausführen; begin FasseEntschluss; BereiteAllesVor; Kaufe; end; |
aber was wäre wenn das nicht nur zwei prozeduren wären, sondern 200 zeilen code die zu TVorgang allein gehören? es ginge auch, aber dann wäre das ganze sehr unübersichtlich (copy&paste-verallgemeinerung). schön wäre es jetzt natürlich wenn wir einfach auf die procedure aus dem vorgänger zugreifen könnten. etwas so:
Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure TKaufVorgang.Ausführen; begin inherited Ausführen; Kaufe; end; |
inherited Ausführen; entspricht also TVorgang.Ausführen. hier wird einfach nur der code aus dem vorgänger in die prozedur geholt, was einem eine menge schreibarbeit ersparen kann.
alles was nun mit kon-/destruktoren und inherited zu tun hat, wurde ja schon beschrieben, vielleicht verstehst du es jetzt?
hoffe sehr, vielleicht ein wenig geholfen haben zu können.
gruß, dmx.
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: So 04.07.04 14:45
Ein Beispiel wo es ohne inherited knallt..? Kein Problem..!
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Menus, ComCtrls, ToolWin, Math;
type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private public end;
TDummyClass = class FMessage: String; public procedure ShowTestMessage; end;
TBaseClass = class private FDummyClass: TDummyClass; public property DummyClassProperty: TDummyClass read FDummyClass; constructor Create; virtual; destructor Destroy; override; end;
TMyClass1 = class(TBaseClass) public constructor Create; override; end;
TMyClass2 = class(TBaseClass) public constructor Create; override; end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TDummyClass.ShowTestMessage; begin ShowMessage(FMessage); end;
constructor TBaseClass.Create; begin inherited; FDummyClass := TDummyClass.Create; FDummyClass.FMessage := 'Test-Message from TDummyClass-Instance'; end;
destructor TBaseClass.Destroy; begin FDummyClass.Free; inherited; end;
constructor TMyClass1.Create; begin inherited; ShowMessage('Constructor of TMyClass1 - uses inherited'); DummyClassProperty.ShowTestMessage; end;
constructor TMyClass2.Create; begin ShowMessage('Constructor of TMyClass2 - doesn''t use inherited'); DummyClassProperty.ShowTestMessage; end;
procedure TForm1.Button1Click(Sender: TObject); begin with TMyClass1.Create do Free; end;
procedure TForm1.Button2Click(Sender: TObject); begin with TMyClass2.Create do Free; end;
end. |
Wie man sieht, einfach eine Form mit 2 Buttons und den Code reinkopiern.. dann siehst du was passieren kann..! 
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 04.07.04 18:57
|
|
|