Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Vererbung - Abspeichen in Streams (https://www.delphipraxis.net/76856-vererbung-abspeichen-streams.html)

benwen 11. Sep 2006 10:44


Vererbung - Abspeichen in Streams
 
Hallo alle zusammen!

Ersteinmal ein großes Lob an dieses Forum und allen, die mir mit ihren Beiträgen schon viel weitergeholfen haben!

Nun zu meiner aktuellen Frage.
Ich habe eine Klassenstruktur definiert, welche der folgenden prinzipiell ähnelt:
Delphi-Quellcode:
Type
  TElement = class
    show: boolean;
    (...)
  end;
 
  TExElement1 = class(TEElement)
    elemID: integer;
    (...)
  end;
 
  TExElement2 = class(TEElement)
    pos: real;
    (...)
  end;

  (...)

  TMyList = class(TList)

  TExElement1List = class(TMyList)
    function GetExElement1(index: integer): TExElement1;
  public
    procedure SaveToStream(Stream: TStream);
    procedure LoadFromStream(Stream: TStream);
    property Items[index: integer]: TExElement1 Read GetExElement1
  end;
 
  TExElement2List = class(TMyList)
  (...) //das gleiche nochmal

implementation
 
  procedure TExElementList.SaveToStream(Stream: TStream);
  var
     NewExElement1: TExElement1;
     i,Len: integer;
  begin
    NewExElement1 := TExElement1.Create;
    Len := Count
    Stream.Write(Len, SizeOf(Len));
    for I := 0 to Count - 1 do
    begin
      NewExElement1 := Items[i];
      with NewExElement1 do
      begin
        Stream.Write(show, sizeof(show));
        Stream.Write(elemID, sizeof(elemID));
        (...)
      end;
    end;
  end;

  procedure TExElementList.LoadFromStream(Stream: TStream);
  var
     NewExElement1: TExElement1;
     i,Len: integer;
  begin
    Stream.Read(Len, SizeOf(Len));
    for I := 0 to Len - 1 do
    begin
      NewExElement1 := TExElement1.Create;
      with NewExElement1 do
      begin
        Stream.Read(show, sizeof(show));
        Stream.Read(elemID, sizeof(elemID));
      end;
    end;
  end;

  function TElement1List.GetExElement1(index: integer): TExElement1;
  begin
    Result := TExElement1(TMyList(self).Items[index]);
  end;

  //und fast genau das gleiche nochmal mit ExElement2...Exelement3 usw.
Wie ihr seht wird das ganze ziemlich umständlich, obwohl alle ExElemente ein paar gleiche Eigenschaften/Variablen haben durch die Vererbung. Jetzt würde ich das ganze gerne etwas rationalisieren.
1. die Methoden der TExElementLists sollten in TMyList allgemein definiert und mittels Vererbung weitergegeben werden (z.B. durch Übermittlung der jeweiligen Klasse (bsp. TExElement1, ...)
2. die Klasse TElement sollte auch schon die Grundeigenschaften in Streams speichern und aus Streams laden können, sodass in den TExElementLists nur noch die zusätzlichen Eigenschaften behandelt werden müssen.

Ist jetzt halbwegs rübergekommen, was ich möchte?
Falls ja, wär es sehr hilfreich wenn mir hier jemand auf die Sprünge hilft. DANKE schomal!

Gruß benwen

KrasserChecker 11. Sep 2006 11:23

Re: Vererbung - Abspeichen in Streams
 
Eine Grundregel von OOP ist ja: Objekte sollten für sich selbst verantwortlich sein.
Daher solltest du in der Basisklasse "TElement" schon mal die beiden Methoden "SaveToStream" & "LoadFromStream" vorsehen (und auch gleich virtuell machen).

Danach schreibst Du deine Liste so um, dass zuerst der Klassename mit weggeschrieben wird. Darüber kannst du beim Laden dann wieder das richtige Objekt erzeugen.

Delphi-Quellcode:
TElement = class
  show: boolean;
  (...)
public
  procedure SaveToStream(Stream: TStream); virtual;
  procedure LoadFromStream(Stream: TStream); virtual;
end;
 
TExElement1 = class(TEElement)
  elemID: integer;
  (...)
public
  procedure SaveToStream(Stream: TStream); override;
  procedure LoadFromStream(Stream: TStream); override;
end;


...

procedure TElement.SaveToStream(Stream: TStream);
begin
  Stream.Write(show, sizeof(show));
end;

procedure TElement.LoadFromStream(Stream: TStream);
begin
  Stream.Read(show, sizeof(show));
end;


procedure TExElement1.SaveToStream(Stream: TStream);
begin
  inherited;
  Stream.Write(elemID, sizeof(elemID));
end;

procedure TExElement1.LoadFromStream(Stream: TStream);
begin
  inherited;
  Stream.Read(elemID, sizeof(elemID));
end;

procedure TElementList.SaveToStream(Stream: TStream);
var i,len: integer;
begin
  len := Count;
  Stream.Write(len, SizeOf(len));
  for i := 0 to Count - 1 do
  begin
    // Länge des Klassennamens & Klassennamen als String wegschreiben, damit
    // wir später wieder ermitteln können, was für eine Klasse dahinter steckt.
    len := Length(Items[i].Classname);
    Stream.Write(len, SizeOf(len));
    Stream.Write(Items[i].Classname, Length(Items[i].Classname));
   
    // Jetzt lassen wir das Objekt sich selbst in den Stream schreiben
    Items[i].SaveToStream(Stream);
  end;
end;

procedure TElementList.LoadFromStream(Stream: TStream);
var NewElement: TElement; i,Len, ObjCount: integer; cn: string;
begin
  Stream.Read(ObjCount, SizeOf(ObjCount));
  for I := 0 to ObjCount - 1 do
  begin
    // Erstmal Klassennamen wieder auslesen und Objekt erzeugen
    Stream.Read(Len, SizeOf(Len));
    SetLength(cn, Len);
    Stream.Read(cn[1], Len);
   
    if cn = 'TElement' then
      NewElement := TElement.Create
    if cn = 'TExElement1' then
      NewElement := TExElement1.Create
    if cn = 'TExElement2' then
      NewElement := TExElement2.Create
    else
      raise Exception.Create('unbekannte Klasse: '+cn);

    // Jetzt lassen wir das Objekt wieder seine Daten auslesen
    NewElement.LoadFromStream(Stream);

    // Objekt mit in die Liste ausnehmen
    Add(NewElement);
  end;
end;

benwen 11. Sep 2006 15:40

Re: Vererbung - Abspeichen in Streams
 
Danke für die schnelle Antwort. Hat mir erstmal sehr viel weitergeholfen!
Ich frag mich jetzt nur noch inwiefern ich mit den Items der ElementList auch auf die erweiterten Eigenschaften von den ExElements zugreifen kann (im weiteren Verlauf des Programms nach dem auslesen des Streams). Geht das so überhaupt oder muss ich dann wieder ExElementLists machen für jedes TExElement??
Gibt es eigentlich sowas wie "upcasten" oder nur downcasen?

gruß benwen

benwen 11. Sep 2006 22:23

Re: Vererbung - Abspeichen in Streams
 
Frage hat sich erledigt


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:41 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 by Thomas Breitkreuz