![]() |
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:
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.
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. 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 |
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; |
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 |
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