Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Verschachtelte Objekte (https://www.delphipraxis.net/76784-verschachtelte-objekte.html)

Sadum 9. Sep 2006 20:55


Verschachtelte Objekte
 
Hallo,

Ich möchte gerne Objekte direkt wie 'Stammbäume' verwalten, um allgemeine Probleme immer weiter in 'Unterobjekte' zu sortieren, anstelle durch Vererbung einen ungeordneten Haufen Nachfahren zu erzeugen.

Also zum Beispiel (Pseudo Code):

Fahrzeug.PKW.Jeep.bauen;

Anstelle von:

PKW = class (Fahrzeug);
Jeep = class (PKW);
Jeep.bauen;

Das Problem ist nur, dass ich zwar Unterobjekte in Objekte stecken kann, diese aber leider die Methoden und Felder des Objektes in dem sie stecken nicht nutzen können (man könnte in Jeep.bauen ja z.B. eine bereits vorhandene Prozedur PKW.bauen des übergeorneten Objekts 'PKW' verwenden wollen), da wenn ich sie als Nachfahren des übergeordneten Objekts deklariere, ich sie nicht auch schon als einen Bestandteil des übergeordneten Objekts verwendet haben darf (was aber für die Schachtelung nötig ist).

mkinzler 9. Sep 2006 20:59

Re: Verschachtelte Objekte
 
Das von dir angestrebte System hat einen eklatanten Nachteil: wenn du einen neuen Nacfahren hinzufügst, mußt du das komplette System anpassen. Ich sehe auch keinen Vorteil in dieser Vorgehensweise. was gefällt dir an Vererbung nicht?

DGL-luke 9. Sep 2006 21:04

Re: Verschachtelte Objekte
 
Hallo, virtuelle Methoden sind dein Mittel der Wahl.

Delphi-Quellcode:
type
  TAuto = class
  public
    procedure Bauen; virtual; abstract;
  end;

  TJeep = class(TAuto)
  public
    procedure Bauen; override;
  end;
So kannst du jederzeit jeep.Bauen oder (jeep as TAuto).Bauen aufrufen, auch wenn du so was hast:

Delphi-Quellcode:
function IrgendeinAuto:TAuto;
begin
  if Random > 0.5 then
    Result := TJeep.Create
  else
    Result := TPKWCreate;
end;
Kannst du sowas machen:

Delphi-Quellcode:
with IrgendeinAuto do
begin
  Bauen;
  {Fahren;
  Verschrotten;} //nur so als beispiel ;)
  Free;
end;
EDIT: Wobei das, was du jetzt hier willst, mir eher sinnlos erscheibnt. So eine Klassen"hierarchie", mein ich :gruebel:

HalloDu 9. Sep 2006 21:06

Re: Verschachtelte Objekte
 
Ich würde es mal so versuchen:
Delphi-Quellcode:
type TPKW = class
     Jeep: TJeep
     procedure Fahren;
     end;
type TJeep = class
     Wuestenjeep: TWuestenjeep;
     GelaendeIndex: Integer;
     end;
type TWuestenjeep = class
     procedure Springen;
     end;
Damit könntest du dann in solche Konstrukte bauen: PKW.fahren; PKW.Jeep.GeleandeIndex; PKW.Jeep.Wuestenjeep.Springen; Trotzdem würde ich dir die gute alte Vererbung empfehlen.

Hoffe es hilt dir beim :coder2:

Mfg HalloDu

EDIT: Ich kann meinen Vorrednern nur zustimmen: Versuch es mit Vererbung.

Sadum 9. Sep 2006 21:19

Re: Verschachtelte Objekte
 
Zitat:

Zitat von mkinzler
Das von dir angestrebte System hat einen eklatanten Nachteil: wenn du einen neuen Nacfahren hinzufügst, mußt du das komplette System anpassen. Ich sehe auch keinen Vorteil in dieser Vorgehensweise. was gefällt dir an Vererbung nicht?

Ich finde damit ist alles einfach besser sortiert.
Delphi selbst verwendet diese Vorgehensweise doch auch:

form1.label1.caption := 'Test';

oder noch stärker bei TWebBrowser:

form1.WebBrowser1.OleObject.document.forms.item(nr ).elements.item(nr).click;

Zitat:

Zitat von HalloDu
Ich würde es mal so versuchen:
Delphi-Quellcode:
type TPKW = class
     Jeep: TJeep
     procedure Fahren;
     end;
type TJeep = class
     Wuestenjeep: TWuestenjeep;
     GelaendeIndex: Integer;
     end;
type TWuestenjeep = class
     procedure Springen;
     end;

Es ist gerade mein Problem, dass eben so etwas nicht geht, weil ich bei der Deklaration von TPKW, den Ausdruck 'Jeep: TJeep'
gar nicht verwenden darf, da TJeep noch gar nicht bekannt ist!

HalloDu 9. Sep 2006 21:26

Re: Verschachtelte Objekte
 
Delphi muss das benutzen, weil dort zuerst einmal die Unterobjekte von TForm verschieden seien können und man z.B. kein TLabel von einer TForm ableiten kann. Diese Hierachie kommt auch zustande weil das TForm Objekt ein Visueller Container ist in den man andere Objekte stecken kann.

Mfg HalloDu

Zu deiner Bemerkung: Die Typen müssen auch so stehen, also letzter Type muss als erstes definiert werden also: 1.Wuestenjeep, 2.Jepp, 3. PKW

EDIT: Und falls du Together hast kannst du Hierachie mit Verebung auch viel besser verwalten als mit deinem Konzept, dass ja nunmal sehr aufwendig ist.

DGL-luke 9. Sep 2006 21:27

Re: Verschachtelte Objekte
 
Das hat aber einen ganz anderen Aufbau! :warn:

Das ist ja keine Klassenhierarchie.

Zwischen
Fahrzeug->PKW->BMW->Z3
besteht doch ein ganz anderer zusammenhang als zwischen
root->node1->properties->name

:shock:

@Dein Problem: "forward declaration"

Delphi-Quellcode:
type
  T1 = class;
  T2 = class
    t1_ding: T1
  end;
  T1 = class
    t2_ding: T2;
Ansonsten, das bei dir ja nur in eine richtung geht, kannst fus einfach umdrehen und zuerst TWüstenAusgrabungsPyramidenFallenAusweichBrückenba uJeep deklarieren :wall:

Sadum 9. Sep 2006 22:20

Re: Verschachtelte Objekte
 
Zitat:

Zitat von DGL-luke
@Dein Problem: "forward declaration"

Delphi-Quellcode:
type
  T1 = class;
  end;
  T2 = class;
    t1_ding: T1;
  end;
  T1 = class
    t2_ding: T2;
  end;

Leider nimmt Delphi bei mir so ein Konstrukt nicht. -> Meldung: Bezeichner redefiniert!

Und mit
Delphi-Quellcode:
type
  Tjeep = class
  public
      procedure fahren;
  end;

type
  Tpkw = class
  public
      gelaendeindex : integer;
      jeep : Tjeep;
  end;

implementation

procedure Tjeep.fahren;
begin
    showmessage ('Jeep fährt'+inttostr(gelaendeindex)); // Fehler
end;
habe ich wie gesagt das Problem, dass Tjeep.fahren nicht auf Variablen des übergeorneten Objekts (gelaendeindex) zugreifen kann.

DGL-luke 9. Sep 2006 22:23

Re: Verschachtelte Objekte
 
Delphi-Quellcode:
type
  T1 = class;
  end;
  T2 = class;
    t1_ding: T1;
  end;
  T1 = class
    t2_ding: T2;
  end;
Das ist nicht das, was ich vorgeschlagen hatte :warn:

HalloDu 9. Sep 2006 22:35

Re: Verschachtelte Objekte
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab jetzt mal kurz ein Beispiel, wie du das haben möchtest geschrieben, aber dabei ist mir aufgefallen, dass auch die Zeilen sehr lang werden.
Hier ist das Beispiel :coder2:

EDIT: An deinem Beispiel siehtst du auch wie unpraktisch dein Konzept ist, denn du kannst nicht auf Variablen und Methoden von Übergeorneten Objekten zugreifen, was bei Vererbung in den meisten Fällen möglich ist.

Sadum 9. Sep 2006 23:03

Re: Verschachtelte Objekte
 
@ HalloDu:

Vielen Dank!
Ja, das mit dem zugreifen auf übergeordnete Variablen ist hier wirklich das Problem.

@ DGL-luke: Habe ich jetzt gesehen :oops:

HalloDu 9. Sep 2006 23:12

Re: Verschachtelte Objekte
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zum Vergleich hab ich das Beispiel noch mal eben mit Verebung geschrieben um zu demostrieren wie das funktioniert.

Hoffe es hilft dir bei deinem Problem. :)

Sadum 14. Sep 2006 22:57

Re: Verschachtelte Objekte
 
Die Vorwärtsdeklaration führte bei mir nur zu abstürzen bei Zugriffen auf die Objekte, aber ich habe das ganze jetzt mit Properties gelöst. So kann ich wenigstens auf Variablen übergeordneter Obejekte zugreifen.

Delphi-Quellcode:
type
  Tjeep = class
  protected
      geschwindigkeit : integer;
  public
      procedure fahren;
  end;

type
  Tpkw = class
  protected
      temp : integer;
      procedure writespeed (speed : integer);
  public
      jeep : Tjeep;
      property geschwindigkeit : integer read temp write writespeed;
  end;

implementation

procedure Tpkw.writespeed (speed : integer);
begin
    temp := speed;
    jeep.geschwindigkeit := temp;
end;

procedure Tjeep.fahren;
begin
    showmessage ('Jeep fährt '+inttostr(geschwindigkeit));
end;
Allerdings bin ich damit meinen eigentlichen Ziel, einen Ersatz für TWebbrowser Anweisungen zu schreiben nicht wirklich näher gekommen, da ich nicht weiß ob man Objekten so wie Prozeduren Argumente übergeben kann.
*Twebbrowser besteht allerdings trotz der "WebBrowser1.OleObject.document.frames.item(0).doc ument.links.item(0).click;" Struktur auch nicht aus verschachtelten Objekten, sondern ist ein Variant (wie auch immer dieser dann konkret aufgebaut ist...)

negaH 15. Sep 2006 01:18

Re: Verschachtelte Objekte
 
Delphi-Quellcode:
WebBrowser1.OleObject.document.frames.item(0).document.links.item(0).click;
ist ebenafalls klassische OOP und könnte inetwa so aussehen:

Delphi-Quellcode:
type
  TWebBrowser = class
    property OleObject: TOleObject;
  end;
 
  TOleObject = class
    property document: TDocument;
    property links: TLinksList;
  end;

  TDocument = class
    property frames: TFrameList;
  end;

  TFrameList = class
    property Item[Index]: TItem;
  end;

  TItem = class
    property document: TDocument;
  end;

  TLinkList = class
    property Item[Index]: TLink;
  end;

  TLink = class
    property OnClick: TNotifyEvent;
  end;

// Hierarchie als Objekte ist dann

  TWebBrowser
    TOleObject
      TDocument
        TFrame(0)
          TDocument
            TLink(0)
            TLink(1)
        TFrame(1)
          TDocument
            TLink(0)
        TLink(0)
        TLink(1)
Um Zugriff von TWebBrowser auf den 1. Frame und dessen 1. Link zu erhalten um dessen OnClick aufzurufen muß man also

WebBrowser.OleObject.Document.Frames.Items[0].Document.Links.Item[0].OnClick; aufrufen. Also EXAKT das was du möchtest und auch nur mit stinknormelem OOP realisiert !

Fazit: Nenne mir bitte ein anders praktisches Beispiel das dein Problem realer erklärt.

Gruß Hagen

DGL-luke 15. Sep 2006 12:14

Re: Verschachtelte Objekte
 
Nein, negaH, das ist nicht das, was er will, siehe meinen beitrag #7.

negaH 15. Sep 2006 12:57

Re: Verschachtelte Objekte
 
Ich weis das es nicht das ist, aber das was er möchte ist das was er als Beispiel mit TWebBrowser angeführt hat. Ergo: er fragt aus meiner Sicht nach einem Konzept, nach Möglichkeit auch umsetzbar. Und das was ich oben aufgezeigt habe ist das was heutztage als OOP Konzept am verbreitesten ist.

Es gibt einen Weg exakt das machen zu können was er sich vorstellt, zumindestens sähe es im Source so aus.

Man arbeitet mit Interfaces -> COM Objecten abgeleitet von IDispatch und deren späten Bindung. Das ist Vergleichbar mit den Ole Objekten beim Zugriff auf ein Word-Dokument.

Allerdings: die Implementierung im Source sieht wieder exakt so aus wie normales OOP nur eben dieses mal zusätzlich noch IINteerfaces basieren auf IDispatch.

In der endgültigen Anwendung wird man nun sein TWebBroweser Objekt als Variant speichern. Zb. so

Delphi-Quellcode:
var
  Obj: Variant;
begin
  Obj := CreateMyObject;
  Obj.Starte.Dies.Und.Mache.Das.An.Position(0).OnCLick;
end;
Da unsere Objekt Instance im Variant Obj ein IDispatch ist und wir als Variante darauf zugreifen KANN der Compiler NICHT wissen welche Eigenschaften, Methoden etc.pp unser Objekt in Obj real implementiert. Also greift die späte Bindung und der Compiler legt im compilierten Code einen String als Konstante ab die etwa so aussieht:

"Starte.Dies.Und.Mache.Das.An.Position(0).OnCL ick"

Das bedeutet das du nun in deiner Objekt Implementation durchaus immer neuere Funktionen/Methoden und Hierarchien anlegen kannst und der Endanwender deiner Lib das erst zur Laufzeit quasi als interpretierbaren String aufruft, späte Bindung halt.

Nur, konzeptionell gesehen wird dann denoch der eigene Code gewohnt als OOP programmiert.

Gruß Hagen

DGL-luke 15. Sep 2006 15:47

Re: Verschachtelte Objekte
 
Er will aber nicht

Erst.A.dann.B.und.da.gehts.noch.weiter.runter

sondern er will

Adam.Kain.Moses.Jesus.Luther, wenn man mal davon ausgeht, dass sich die vererben....

Für einen Fall wie in TTreeNodes oder im Document Object Model kann ich das auch nachvollziehen. Aber nicht für Klassenmodellierung.
Ich finde erstens das Ziel grässlich und zweitens jede mögliche Umsetzung mindestens genauso grässlich. Und auch dein

Zitat:

zumindestens sähe es im Source so aus.
führt zu einer Vergewaltigung sämtlicher Prinzipien des COM-Modells und der OOP.

negaH 15. Sep 2006 18:19

Re: Verschachtelte Objekte
 
Zitat:

Adam.Kain.Moses.Jesus.Luther, wenn man mal davon ausgeht, dass sich die vererben....
Hm, sorry wie bescheuert ist das denn ?

Wenn wir also zb. wie bei der VCL auf ein TEdit zugreifen wollen dann müssten wir also immer so arbeiten

if TObject.TPersistent.TComponent.TCustomControl.TWin Control.TCustomEdit.TEdit.?????.Cpation = 'Test' then

Also ehrlich gesagt verstehe ich den Sinn nicht dabei. Wir dereferenzieren damit ja immer nur eine Klassenhierarchie und keine lebendigen Objecte. Deshalb auch die Fragezeichen ???? in dieser Kette, denn normalerweise wollen wir ja eine Instance einer Klasse von TEdit die auf einem TForm liegt ansprechen.
Desweiteren kann es keine multiplen TEdit auf einem Form geben, da es ja nur eine eindeutige Klasse TEdit geben kann.

Ich glaube ich muß den Thread ein Drittes mal komplett lesen damit ich die Frage verstehe ? Bin nur ich so blöde ?

Gruß Hagen

DGL-luke 15. Sep 2006 19:18

Re: Verschachtelte Objekte
 
:lol:

Diese Antwort hatte ich jetzt nicht erwartet, aber genau das will der Thread-Ersteller (nb! nicht ich):

Zitat:

Fahrzeug.PKW.Jeep.bauen;
Aber ich kann dir vollkommen nachfühlen! :) :dp:


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:18 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz