AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Fragen zu OOP und Klassen

Ein Thema von Gonzo2 · begonnen am 22. Nov 2007 · letzter Beitrag vom 23. Nov 2007
Antwort Antwort
Seite 2 von 3     12 3      
Gonzo2

Registriert seit: 4. Nov 2007
42 Beiträge
 
#11

Re: Fragen zu OOP und Klassen

  Alt 23. Nov 2007, 08:35
Vielen Dank an alle die mit mir meine Verständnisfragen durchgenommen haben. inherited ist mir jetzt klarer. Abschließend kann man sagen, daß inherited einfach nur den Vorfahr aufruft. Was sich so einfach anhört ist Anfängern nicht sofort klar. Erst wenn man die Konsequenzen sieht wird es klarer. In einer Klasse die auf TObject aufbaut kann man in Create auf inherited verzichten, da im Create von TObject, also dessen Vorfahr, nichts passiert. Beim Arbeiten mit anderen Vorfahrklassen könnte dagegen der fehlende Aufruf von inherited böse Folgen haben, da dann der Vorfahr nicht aufgerufen wird und später einige geerbte Eigenschaften oder Methoden ins leere laufen.

Hier ein Beispiel das ich mir zum Verständnis erstellt habe. Ich hab mir eine eigene IniFile Klasse geschrieben bei der nur Create ersetzt wurde. Rufe ich kein inherited auf, hat das Konsequenzen und im Beispiel tritt bei WriteString ein Fehler auf.

Delphi-Quellcode:
type
  TMeineIniFile = class(TIniFile)
  public
    constructor Create(const FileName: string);
  end;

constructor TMeineIniFile.Create(const FileName: string);
begin
  //inherited Create(FileName); //mal mit mal ohne
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  IniFile: TMeineIniFile;
begin
  IniFile := TMeineIniFile.Create('c:\temp\tmp.ini');
  try
    IniFile.WriteString('a', 'b', 'Gefunden');
    ShowMessage(IniFile.ReadString('a', 'b', 'Nicht gefunden'));
  finally
    IniFile.Free;
  end;
end;
Zwar sind einige meiner Fragen zu inherited noch nicht beantwortet, aber an dieser Stelle genügt es. Ich hacke später nochmal nach.
  Mit Zitat antworten Zitat
Gonzo2

Registriert seit: 4. Nov 2007
42 Beiträge
 
#12

Re: Fragen zu OOP und Klassen

  Alt 23. Nov 2007, 08:52
Weiter in Verständnisfragen zu Klassen: private, public, published und protected

Neue Fragen, neuer Thread. Hier geht es zu Fragen zu OOP und Klassen: published, protected, ...
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#13

Re: Fragen zu OOP und Klassen

  Alt 23. Nov 2007, 08:57
halt dich bei inherited nicht zu sehr am Constructor auf. Inherited leitet einen ganz normalen Methodenaufruf ein. eben nur mit dem Unterschied, dass man die Vorfahrklasse meint. Man kann inherited in jeder Methode nutzen.

Der Constructor ist eben eine ganz normale Methode, die nach ein paar Ergänzungen etwa so aussieht:
Delphi-Quellcode:
procedure myconstructor(param1,param2:integer; und hier die restlichen Parameter);
//param1 und param2 sind "versteckte Parameter" welche immer übergeben werden, wenn statt procedure constructor da steht
begin
  //so und jetzt der Code, der eigentlich vor begin steht
  if param2=1 then
  begin
    //param2=1, wenn man TMyClass.create aufruft
    self:=System.ClassCreate(param1); //param1 ist ein Pointer auf die RTTI der Klasse
    //System.ClassCreate reserviert den Speicher für alle Felder (wird wie ein Record behandelt)
    //und ruft noch self.afterconstruction auf, was meist leer ist
  end
  else
    //param2=0 wenn man myClass.Create oder eben self.Create oder inherited create aufruft
    self:=param1; //Jede Methode hat einen ersten versteckten Parameter, und der ist immer self
 
  //und erst hier kommt dein normaler Code aus der Methode/ dem Constructor
end;
Eigentlich könnte der Programmierer, dass ja auch selber erldigen.
Wenn er eine neue Instanz einer Klasse initialisieren will, kann er ja selber ClassCreate aufrufen. In Pascal/Delphi ist es halt einfacher: Da man ja meist eh irgendwelche wichtigen Initialisierungen des Objektes (z.B. IniFile öffnen) machen muss, hat man irgendeine Init-Methode. Also man würde meist ClassCreate aufrufen und dann die Init-Methode. Dies wurde einfach zusammengelegt und nennt sich jetzt Constructor. Und weil halt in den Constructoren meist wichtige Sachen erledigt werden, ist es günstig den Constructor des Vorfahren auch mit aufzurufen (ist ja nur zur Initialisierung).
Und wie gesagt: Bei anderen (virtuellen) Methode kann das auch sinnvoll sein. Es sei denn man überschriebt sie, weil man eben nicht will, was in der Vorfahrklasse gemacht wurde.


Edit: neue Frage, neuer Thread. Sonst kommen wir hier ganz durcheinander
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Gonzo2

Registriert seit: 4. Nov 2007
42 Beiträge
 
#14

Re: Fragen zu OOP und Klassen

  Alt 23. Nov 2007, 09:20
Danke Dir, war noch eine gute Ergänzung. Du hast Recht, inherited wird nicht nur in Create angewendet. Jedes mal wenn man eine Methode ergänzt oder ändert, ruft man die Vorfahrmethode auf. Nur kommt bei den Beispielen am häufigsten inherited in Create und Destroy vor.

Zitat von sirius:
Edit: neue Frage, neuer Thread. Sonst kommen wir hier ganz durcheinander
Ich hoffe nicht. Das Thema ist Verständnisfragen zu OOP und Klassen. Am liebsten wäre mir alles in einem Thread. Sollte das nicht funktionieren, kann man bei weiteren Verständnisfragen neue Threads öffnen, auch wenn sie dann das Thema verteilen.


Edit: vielleicht hast du Recht. Vielleicht kommt man doch zu sehr durcheinander. Ich hab eine neues Thema erstellt und die Themen gesenseiteig verlinkt. Somit will ich auch für Andere die das Thema interessiert eine Art Roten Faden durch das Thema ziehen.
  Mit Zitat antworten Zitat
Tyrael Y.

Registriert seit: 28. Jul 2003
Ort: Stuttgart
1.093 Beiträge
 
Delphi 2007 Professional
 
#15

Re: Fragen zu OOP und Klassen

  Alt 23. Nov 2007, 09:25
Zitat von Gonzo2:
Zitat von Tyrael Y.:
Im ersten Fall könnte dein Objekt freigegeben werden, im zweiten Fall wird es garantiert freigegeben.
Ja. Das ist kein unwichtiger Punkt, aber an dieser Stelle nicht so wichtig. Es ist schon klar, daß Objekte in einen Schutzblock gehören, aber bei Verständnisfragen ist alles was von dem Notwendigen ablenkt zuviel. Deshalb habe ich hier bei den Beispielen mit voller Absicht auf den Schutzblock verzichtet. Sonst werden bei mir Objekte eingepackt.
Es ging mir NICHT um den Schutzblock, sondern um das defensive Programmieren, was ich anhand eines Schutzblockes zeigen wollte.
Levent Yildirim
Erzeugung von Icons aus Bildern:IconLev
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#16

Re: Fragen zu OOP und Klassen

  Alt 23. Nov 2007, 09:30
Zitat von Gonzo2:
Nur kommt bei den Beispielen am häufigsten inherited in Create und Destroy vor.
Weil genau die wichtigsten Initialisierungen gemacht werden, die notwendig sind, damit die Klasse überhaupt benutzt werden kann (siehe dein Inifile-Beispiel)

Zitat von Gonzo2:
Ich hoffe nicht. Das Thema ist Verständnisfragen zu OOP und Klassen. Am liebsten wäre mir alles in einem Thread. Sollte das nicht funktionieren, kann man bei weiteren Verständnisfragen neue Threads öffnen, auch wenn sie dann das Thema verteilen.
Das Thema sollte eigentlich auch eher exkater formluiert werden / an die "erste Frage" angepasst werden.

du musst im Auge behalten, dass dieser Thread nicht nur für dich ist, sondern in Zukunft auch über Suchmaschinen oder die interne Suche von anderen aufgerufen wird. Und für die wäre so ein Thread mit mehreren Themen keine Hilfe
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Gonzo2

Registriert seit: 4. Nov 2007
42 Beiträge
 
#17

Re: Fragen zu OOP und Klassen

  Alt 23. Nov 2007, 09:49
Hast Recht, ich hab es geändert und neues Thema erstellt. Ich hab die beiden Themen gegenseitig verlinkt, so daß jedes Thema zwar für sich ist, aber jeder Interessierte auch weitere Fragen lesen kann. Es werden noch paar Threads werden.

An einen Moderator der das liest. Bitte Anfangstitel in Fragen zu OOP und Klassen: inherited ändern.
  Mit Zitat antworten Zitat
Gonzo2

Registriert seit: 4. Nov 2007
42 Beiträge
 
#18

Re: Fragen zu OOP und Klassen

  Alt 23. Nov 2007, 15:35
Vielleicht noch eine Frage zu Create. Deswegen lohnt nicht ein extra Thread und wir haben hier sowieso viel über Create diskutiert.

In der Regel wird nur ein Create benötigt, man kann aber mehrere erstellen.

Delphi-Quellcode:
type
  TMyClass = class
  private
    fCreated: TDateTime;
  public
    constructor CreateA();
    constructor CreateB(Int: Integer);
    function getCreated: TDateTime;
  end;

constructor TMyClass.CreateA();
begin
  fCreated := now;
end;

constructor TMyClass.CreateB(Int: Integer);
begin
  fCreated := now + Int;
end;

function TMyClass.getCreated: TDateTime;
begin
  result := fCreated;
end;
Der Konstruktor reserviert Speicher, füllt den mit Nullen usw. Rufe ich also CreateA auf, ist alles klar, es wird ein Objekt erstellt. Was passiert aber wenn ich hinterher CreateB aufrufe?

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  MyClass: TMyClass;
begin
  MyClass := TMyClass.CreateA;
  try
    ShowMessage(DateToStr(MyClass.getCreated));
    MyClass := TMyClass.CreateB(10);
    ShowMessage(DateToStr(MyClass.getCreated));
  except
    MyClass.Free;
  end;
end;
Eine Fehlermeldung gibt es nicht, warum auch. Aber was passiert hier? Wird ein zweites Objekt erstelt? Oder bleibt es das Objekt, nur bekommt das Objekt einen neuen Anfangszustand? Wird alles wieder genullt? Oder wird einfach nur fCreated neu gesetzt? Was passiert wenn der Kreator das zweite mal aufgerufen wird?
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#19

Re: Fragen zu OOP und Klassen

  Alt 23. Nov 2007, 16:02
In deinem Beispiel ist es ein Problem.
MyClass ist ja nur ein Zeiger auf eine Instanz deiner Klasse. Letztenendes ist es nur ein Record, welches als erstes Element einen Zeiger auf die Klasse (also die RTTI) hat.

Ein Objekt besteht ja immer aus dem Bauplan (die RTTI) und den Methoden der Klasse. Die gibts in jedem Programm nur einmal. Und dann gibts eben noch die Instanz, was im Prinzip der oben beschriebene Record ist.
Rufst du jetzt zweimal einen Constructor mit TmyClass.Create auf (also so dass innerhalb des constructors ClassCreate aufgerufen wird) bekommst du jedes Mal einen Zeiger auf das neue Record zurück. Dadurch dass die zwei Constructoren unterschiedlich sind, sind die Records womöglich unterschiedlich initialisiert (je nachdem, was in dem jeweiligen Constructor drin steht).

In deinem Besipiel überschreibst du den Zeiger auf den ersten Record und bekommst dadurch ein Speicherloch (du kannst den Speicher nicht mehrfreigeben, da du nicht mehr weist, wo er ist). Und bei einem Speicherloch meckert kein compiler und auch kein Processor und auch kein Windows. Ausser es ist dann irgendwann nach vielen Aufrufen kein freier Speicher mehr da.

Speichertechnisch gleiches erriechst du mit folgendem Code:
Delphi-Quellcode:
type PmyInstance=^TmyInstance;
     TmyInstance=record
       RTTI:pointer; // der besagte erste Zeiger auf die RTTI
       fCreated:Tdatetime;
end;
...

procedure inita(Instance:PmyInstance);
begin
  Instance.fcreated:=now;
end;
procedure initb(Instance:PmyInstance;int:integer);
begin
  Instance.fcreated:=now+int;
end;



var myInstance:PmyInstance;
begin
  new(myInstance);
  inita(myInstance);

  new(myInstance);
  initb(myInstance);

  dispose(myInstance);
end;
Ist fast dasselbe wie OOP, nur dass hier keine Veerbung, Polymorphie, etc. möglich ist. Und daran siehst du auch, warum man new und init zu einem Constructor zusammengefasst hat. Und du siehst auch, dass ich den Speicher vom ersten "new" nicht mehr freigeben kann.

Was man aber an deinem Code machen kann, ist den zweiten Constructor als normale Methode aufzurufen (param2=0):
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  MyClass: TMyClass;
begin
  MyClass := TMyClass.CreateA;
  try
    ShowMessage(DateToStr(MyClass.getCreated));
    MyClass.CreateB(10); //hier ist der Unterschied, CreateB wird als normale Methode aufgerufen (ohne ClassCreate)
    ShowMessage(DateToStr(MyClass.getCreated));
  except
    MyClass.Free;
  end;
end;
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Gonzo2

Registriert seit: 4. Nov 2007
42 Beiträge
 
#20

Re: Fragen zu OOP und Klassen

  Alt 23. Nov 2007, 18:36
Ich frage deshalb, weil ich irgendwann irgendwo gelesen habe, daß immer nur ein Konstrukt ausgeführt wird egal wie viele Konstrukte eine Klasse hat. Ich weiß aber leider nicht mehr wo das stand. Es stand da in etwa, daß nur der erste Create den Speicher reserviert. Die anderen sollen dann nur noch alles zwischen begin und end ausführen, aber das Objekt nicht mehr initialisieren. Ich such das mal.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:48 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz