Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 04, 2025 15:55

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 13 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Vererbung und Polymorphie
BeitragVerfasst: So Mai 15, 2011 00:30 
Offline
DGL Member

Registriert: Do Mai 05, 2011 14:43
Beiträge: 17
Abgetrennt von Pointer auf Proceduren durch Horazont

Ok super. Damit haben sich alle Fragen geklärt und ein dickes Danke.

Übrigens, warum ich anch den Stacks gefragt habe. Die angesprochene Proxy-Methode lässt sich dadurch recht einfach machen. Ich habe einen "Master"-Stack in dem alle Klassen drinn gespeichert sind die auf OnTimer reagieren sollen. Jedes mal bei OnTimer kopiere ich den inhalt des "Master"-Stacks in einen temporären stack und lasse den dann Ler laufen und jedes Klasse reagieren.

Edit: Mir hat sich eine Frage zum thema TObject. Könnte ich in einer Klasse auch eine Variable von TObject deklarieren (in dem fall einen pointer) und dann auf eine Procedure dieser Variable zugreifen? (A : TObject;A.doSonething) Also könnte ich zwei verschiedene klassen nutzen (vorrausgesetzt sie besitzen beide die Procedure DoSomething. Ansonsten könnte das problematisch werden).


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Pointer auf Proceduren
BeitragVerfasst: So Mai 15, 2011 10:32 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Mietfekatfe hat geschrieben:
Mir hat sich eine Frage zum thema TObject. Könnte ich in einer Klasse auch eine Variable von TObject deklarieren (in dem fall einen pointer) und dann auf eine Procedure dieser Variable zugreifen? (A : TObject;A.doSonething) Also könnte ich zwei verschiedene klassen nutzen (vorrausgesetzt sie besitzen beide die Procedure DoSomething. Ansonsten könnte das problematisch werden).

So ganz verstehe ich die Frage nicht. Wahrscheinlich ist es besser, wenn du die nochmal ausformulierst und in einem neuen Thread postest.

greetings

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Pointer auf Proceduren
BeitragVerfasst: So Mai 15, 2011 14:23 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

nein das geht nicht. Wenn du das machen willst, dann mach dir eine Klasse

Code:
  1. TBasicClass = class(TObject)
  2. public
  3.   procedure DoSomething; abstract; virtual;
  4. end;
  5.  
  6. TChildClass1 = class(TBasicClass)
  7. public
  8.   procedure DoSomething; override;
  9. end;
  10.  
  11. TChildClass2 = class(TBasicClass)
  12. public
  13.   procedure DoSomething; override;
  14. end;


Jetzt kannst du dir Objekte der Klassen TChildClass1 und TChildClass2 anlegen un die als TBasicClass speichern. Wenn du dann DoSomething aufrufst, dann wird die Methode in der Kindklasse ausgeführt. Zur Erklärung: das abstract sagt, das die Methode nur ein Platzhalter für die Kindklassen ist und das virtual sagt, das die Methode von der Kindklasse überschrieben wird. Du kannst das abstract auch weg lassen, dann musst du die Methode auch in der TBasicClass implementieren und kannst dort noch Code einfügen der für beide Kindklassen gilt.

Noch was zu deinem Stack. Nimm lieber ne Liste un lauf da mit ner Schleife durch, da kann man die Pointer auch leichter wieder löschen, wenn ein Objekt freigegeben wird. Und du musst nich jedesmal ne Kopie anlegen. Das frisst nur unnötig Performance ;)

MfG Bergmann.

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Zuletzt geändert von Bergmann89 am Mo Mai 16, 2011 14:15, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Pointer auf Proceduren
BeitragVerfasst: So Mai 15, 2011 14:30 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Dez 11, 2009 08:02
Beiträge: 532
Programmiersprache: pascal (Delphi 7)
Zitat:
Also könnte ich zwei verschiedene klassen nutzen
Wenn die Klassen beide ihre DoSomething() methode von einer gmeinsamen Basisklasse erben (oder von einem Interface) dann geht das ohne Probleme
Code:
  1. A: TObject;
  2. //...
  3. (A as TSomeCommonBaseClassThatDeclaresDoSomething).DoSOmething(); //Vorausgesetzt, A enthält tatsächlich eine Instanz dieser Klasse oder einer davon abgeleiteten
Probleme gibts nur, wenn sie nicht von einer gemeinsamen Basisklasse erben. Dann gibts natürlich noch die Möglichkeit, Interfaces zu benutzen, allerdings darf in Pascal soweit ich weiß nur TInterfacedObject (davon abgeleitete Klassen natürlich) Interfaces implementieren. Wenn keines von beiden möglich ist, dann dürfte wirklich die einzige Möglichkeit sein
Code:
  1. if a is TSomeClassThatDeclaresDoSomething then (a as TSomeClassThatDeclaresDoSomething).DoSomething()
  2. else if a is TAnotherClassThatDeclaresDoSomething then (a as TAnotherClassThatDeclaresDoSomething).DoSomething() {...}


Hab ich die Frage richtig verstanden, oder meinst du was ganz anderes?

edit: war wer schneller


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Pointer auf Proceduren
BeitragVerfasst: So Mai 15, 2011 15:11 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
sharkman hat geschrieben:
allerdings darf in Pascal soweit ich weiß nur TInterfacedObject (davon abgeleitete Klassen natürlich) Interfaces implementieren.

Falsch. Jede beliebige Klasse kann beliebige Interfaces implementieren.

greetings

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Pointer auf Proceduren
BeitragVerfasst: So Mai 15, 2011 21:31 
Offline
DGL Member

Registriert: Do Mai 05, 2011 14:43
Beiträge: 17
sharkman: so in der art ja.
Meine Ideen dementsprechend sind nun auch zu einer anderen Idee, weg von dem Stack, gewander.

Eine Klasse TClassContainer welche ein Array von TObject enthält. Nun kann ich mit einer entsprechenden add Procedure eine beliebige Klasse (ich gehe davon aus das ich hinter das Class entsprechend TObject schreiben muss) in den Container reinladen und entsprechend darauf zugreifen (die Größe des Container wird auch entsprechend gespeichert bla bli blub). So weit ich dass nun aber verstanden habe wird es nicht so funktionieren und ich muss quasi für jede neue Klasse auf die ich auf diese art zugreifen will eine neue Containerklasse schreiben.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Pointer auf Proceduren
BeitragVerfasst: Mo Mai 16, 2011 00:11 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

was genau hast du denn vor? Auf was willst zu zugreifen? Mach mal ein Bsp mit den 2 verschiedenen Klassen. Und warum machst du dir selber die Mühe uns schreibst dir ein Array und haufen Methoden. Nimm noch ne Liste, wie ich oben schon gesagt hab. Da is schon alles fertig implementiert --> TList!

Und nur als Anmerkung, aber TClassContainer ist imho nicht die richtige Wortwahl und führt später zu Verwirrung. Klassen sind nur Baupläne für Objekte. Das Objekt is das was du benutzt und mit dem du arbeitest. Also wäre der Name TObjectContainer vlt etwas angebrachter. Dafür gibts auch ne Liste. die verwaltet Objekte und gibts sie ggf frei, wenn die gelöscht werden --> TObjectList ;)

MfG Bergmann.

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Pointer auf Proceduren
BeitragVerfasst: Mo Mai 16, 2011 10:27 
Offline
DGL Member

Registriert: Do Mai 05, 2011 14:43
Beiträge: 17
tatsache, TList scheint genau das zu sein ich machen wollte.

Ein Beispiel. Es geht darum das ich mir Klassen schreiben möchte um Primitves zu auszugeben. Also eine Klasse für Sechsecke eine für Vierecke etc. Diese unterscheiden sich ja prinzipiel in kleinigkeiten (im inhalt der Draw Procedure, nicht aber im Namen ebend dieser). Nun kam mir grade die idee mit den Kinderklassen. Ich baue eine Basisklasse in der die wichtigeten informationen enthalten sind un ein Pointer auf eine Procedure mit dem namen Draw. Nun baue ich die verschiedenen Klassen für verschiedene Primitves. Jeder dieser liegt die basisklasse zu grunde. Jeder primitve kriegt eine Draw procedure die ich dann auf den Pointer der Basisklasse verweise. Nun müsste ich ja entsprechend darauf zugreifen können. (Konfus.) Oder greifen hier entsprechend die Interfaces? (Habe nicht ganz verstanden wie die wirken).

Die Listen brauche ich um alles (wie am Anfang vom Thread gesagt) alle DrawFunktionen geordnet auf einen einzelnen Timer reagieren zu lassen. Und hier greift wieder die Problematik, es gibt nicht nur eine einzelne Draw funktionen sonder verschiedene.


Edit: Beispiel wie ich mir das ganze vorstellte, klappt leider so nicht.
Code:
  1.   TBasis = class
  2.     private
  3.     public
  4.       Draw: procedure of object;
  5.     end;
  6.  
  7.   TVater= class
  8.     private
  9.     public
  10.       var Kind : TBasis;
  11.       procedure SagHallo;
  12.     end;
  13.  
  14.    TMutter= class
  15.     private
  16.     public
  17.       var Kind : TBasis;
  18.       procedure Saggarnichts;
  19.     end;
  20. var
  21.   Form1: TForm1;
  22.   Mama : TMutter;
  23.   Papa : TVater;
  24.   Haus : array [0..1] of TObject;
  25.  
  26. implementation
  27.  
  28. {$R *.dfm}
  29. procedure TMutter.Saggarnichts;
  30. begin
  31. ShowMessage('garnichts');
  32. end;
  33.  
  34. procedure TVater.SagHallo;
  35. begin
  36. ShowMessage('Hallo');
  37. end;
  38.  
  39. procedure TForm1.FormCreate(Sender: TObject);
  40. begin
  41. Mama := TMutter.create;
  42. Papa := TVater.create;
  43. Mama.Kind.Draw:= Mama.Saggarnichts;
  44. Papa.Kind.Draw:= Papa.SagHallo;
  45.  
  46. Haus[0] := Mama;
  47. Haus[1] := Papa;
  48.  
  49. Haus[0].Kind.Draw;
  50. Haus[1].Kind.Draw;
  51.  
  52.  
  53. end;


Zuletzt geändert von Mietfekatfe am Mo Mai 16, 2011 11:27, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Vererbung und Polymorphie
BeitragVerfasst: Mo Mai 16, 2011 10:32 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Das was du willst nennt man Polymorphie und Vererbung. Das sind Grundlagen der Objektorientierten Programmierung. Ich schlage vor, du liest dich schonmal etwas ein und heute Abend poste ich dir eine genauere Erklärung (ich muss jetzt leider weg), bzw. bis dahin hat vielleicht schon jemand anderes eine ausführlichere Antwort gegeben.

greetings

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Vererbung und Polymorphie
BeitragVerfasst: Mo Mai 16, 2011 14:12 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Mietfekatfe: Es ist oftmals wesentlich besser zu erklären, was man eigentlich vor hat als nach einer Lösung für ein Problem zu suchen. Denn oftmals ist es auch schon so, dass die Probleme die man hat eigentlich gar nicht wirklich existent sind. Bzw. es von Grund auf eine ganz einfachere Lösung für alles gut. Wenn man aber nach einem konkreten Problem fragt, dann neigt die Menschheit dazu sich auf dieses Problem zu stürzen antelle sich auf die Suche nach dem echten Problem zu machen. ^^

Bergmann89: So ganz unrecht hast du ja nicht, aber wenn du Code postest, dann achte bitte auf dessen Korrektheit. Ansonsten kann es schnell passieren, dass dessen Wirkung verpufft und der Hilfesuchende eher verunsichert wird.

Mietfekatfe: Um dein Beispiel mal zu entwirren und zu versuchen ohne groß mit Fachwörtern um mich zu werfen.
TBasic ist die Basisklasse. Diese definiert die Methode Draw. Draw ist virtual abstract und kann (muss) von abgelittenen überschrieben werden. Die von TBasic abgelittenen Klassen steuern dann lediglich die Funktion Draw bei. Virtual ist wichtig damit Draw von TFather nach TBasic gereicht wird. Abstract definiert nur, dass TBasic keine eigene Implementierung von Draw hat. Beim Erstellen musst du dann TFather oder TMother erstellen. Für den Rest genügt es, wenn du die Objekte als TBasic behandelst. (Kommentare im Code sind nur für dich zum Verständnis)
Code:
  1. type
  2.   TBasic = class // Basisklasse
  3.   public
  4.     Draw; virtual; abstract; // Definition der Methode
  5.   end;
  6.  
  7.   TFather = class(TBasic) // Klasse abgelitten von TBasic
  8.   public
  9.     procedure Draw; override; // Draw aus Vorfahren überschreiben
  10.   end;
  11.  
  12.   TMother = class(TBasic) // Klasse abgelitten von TBasic
  13.   public
  14.     procedure Draw; override; // Draw aus Vorfahren überschreiben
  15.   end;
  16.  
  17. implementation
  18.  
  19. {$R *.dfm}
  20.  
  21. procedure TFather.Draw;
  22. begin
  23.   ShowMessage('Hallo');
  24. end;
  25.  
  26.  
  27. procedure TMother.Draw;
  28. begin
  29.   ShowMessage('garnichts');
  30. end;
  31.  
  32.  
  33. procedure TForm1.FormCreate(Sender: TObject);
  34. var
  35.   House: array [0..1] of TBasic;
  36. begin
  37.   // Die können hier auch direkt in House gepackt werden
  38.   House[0] := TMother.Create;
  39.   House[1] := TFather.Create;
  40.  
  41.   House[0].Draw;  // Ruft TMother.Draw auf obwohl du nur TBasic kennst
  42.   House[1].Draw;  // TFather.Draw
  43. end;


Wenn du ein Array of TObject oder eine TObjektList hast, dann musst du die Instanzen deiner Objekte noch auf TBasic casten. Das geht entweder mit TBasic(House[0]) als harter Cast oder mit (House[0] as TBasic) als sichere Typprüfung. Ein harter Cast nimmt das Objekt und benutzt es einfach als TBasic. Wenn es aber kein TBasic ist kann sonstwas passieren. Ab TObject als Ausgangstyp kannst du den Operator AS benutzen. Mit diesem wird überprüft ob das Objekt vom Typ TBasic oder ob TBasic irgendwo in der Hirarchie ist. Wenn nicht wird eine Fehler (Exception) ausgelöst. Wenn doch wird die Funktion ausgelöst. Wenn auch andere Typen enthalten sein können, dann solltest du mit IS überprüfen. Wie sharkman das gepostet hat. Auch wenn dessen Bezeichner recht verwirrend lang sind.

In Code könnte das so aussehen. (Für TObjectList)
Code:
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.   House: array [0..1] of TObject;
  4. begin
  5.   House[0] := TMother.Create;
  6.   House[1] := TFather.Create;
  7.  
  8.   (House[0] as TBasic).Draw;
  9.   (House[1] as TBasic).Draw;
  10. end;


Bzw als Pointer so. Wenn du ausschließlich nur TBasic in die Liste packst dann kannst du auch direkt casten. Ansonsten überürfen. (Für TList)
Code:
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.   House: array [0..1] of Pointer;
  4. begin
  5.   House[0] := TMother.Create;
  6.  
  7.   // Direkt casten
  8.   TBasic(House[0]).Draw;
  9.  
  10.   // Erst überprüfen dann casten
  11.   if (TObject(House[0]) is TBasic) then
  12.     TBasic(House[0]).Draw;
  13. end;


Zu erst IS und dann AS macht eher keinen Sinn, da es doppelt überprüft wird. Es sei denn du änderst oft die Typen und möchtest immer auf nummer Sicher gehen.

PS: Du solltest dir angewöhnen Bezeichner englisch zu benennen. Alles Andere gehört sich nicht. ;)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Vererbung und Polymorphie
BeitragVerfasst: Mo Mai 16, 2011 15:28 
Offline
DGL Member

Registriert: Do Mai 05, 2011 14:43
Beiträge: 17
Danke. Du hast das Problem genau bennen können und hast es leicht verständlich erklärt. Vor allem das mit dem Override und Abstract wird mir in vielerlei hinsicht helfen. Wieder einmal etwas gelernt :)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Vererbung und Polymorphie
BeitragVerfasst: Mo Mai 16, 2011 15:51 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Bitte Bitte. Wobei Bergmann das schon versucht hat aber leider etwas vergessen hatte. Ich muss auch gestehen, dass ich auch erst in den letzten Posts dein Problem richtig verstanden habe. Also ohne die Vorarbeit von allen wär das auch nicht drin gewesen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Vererbung und Polymorphie
BeitragVerfasst: Mo Mai 16, 2011 18:14 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

ja, ich hab vergessen die BasisKlasse in den Kindklassen einzutragen, also war da keine Vererbung. Ich habs jetzt aber korrigiert, nich das es später nochma zu Verwirrungen kommt^^

MfG Bergmann.

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 13 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 15 Queries | GZIP : On ]