![]() |
Interfaces Generics
Eine kurze Frage zum Thema.
Wie muss Ich meinen Code ändern damit der "Publisher" Elemente, welche das Interface "ISubscriber" implementieren, aufnimmt?
Delphi-Quellcode:
Ich kann die Generische Klasse aber nur mit einem konkreten Klassen-Parameter vererben oder instanzieren.
ISubscriber = interface
procedure GetNewspaper(Newspaper : TNewspaper); end; // Die generische Liste soll Elemente, welche das Interface implementieren, verwalten TPublisher = class(TObjectList<ISubscriber>) public procedure AddSubscriber(ISubscriber); procedure RemoveSubscriber(ISubscriber); procedure MessageAllSubscriber; end; Ich will aber das da oben :( Wieso sollte meiner generischen Liste nicht das Interface genügen? Das wäre echte Kapselung. Was kann ich machen? |
AW: Interfaces Generics
Zitat:
Delphi-Quellcode:
type
ISubscriber = interface procedure GetNewspaper(Newspaper : TObject); end; // Die generische Liste soll Elemente, welche das Interface implementieren, verwalten TPublisher = class(TList<ISubscriber>) public procedure AddSubscriber(S: ISubscriber); procedure RemoveSubscriber(S: ISubscriber); procedure MessageAllSubscriber; end; Erklärung: TList kann Schnittstellen, TObjectList nicht. Stilistisch würde ich aber keine AddSubscriber / RemoveSubscriber Methoden deklarieren, denn wenn diese eigenen Code enthalten der in der Oberklasse Add/Remove Methode nicht enthalten ist, könnten Klienten der Klasse weiter auf Add/Remove zugreifen (absichtlich oder unabsichtlich) und damit den eigenen Code umgehen. |
AW: Interfaces Generics
Liegt das einfach daran, das Add und Sub aus IMath und _AddRef, _Release und QueryInterface aus IInterface dort nicht implementiert sind?
Ich wollte doch auchnoch das Typecasting umgehen. Ach Ich sehe grade, du verwendest auch die generische TList. Okay gut. Und wenn Ich jetzt noch sowas wie OwnsObjects haben möchte? Selbst schreiben? |
AW: Interfaces Generics
OwnsObjects bei interfaces ?
|
AW: Interfaces Generics
Ja "OwnsObjects bei interfaces" . Das wäre nett.
Aber ich merke schon an der Art deines Posts, da will ich scheinbar zu viel / etwas was nicht möglich ist. Auf das ich mit nachdenken wohl auch selbst kommen sollte. ;) |
AW: Interfaces Generics
Zitat:
Delphi-Quellcode:
In dem oberen Beispiel kann Ich ja auch noch die generische Version der TList nehmen.
TPublisher
private Subscribers : TList; public procedure AddSubscriber(Subscriber : ISubscriber); procedure RemoveSubscriber(Subscriber : ISubscriber); |
AW: Interfaces Generics
Wenn du im zuletzt geposteten Beispiel die Subscriber in einer TList speicherst, haust du dir u.U. den RefCount kaputt. Denn das AddSubscriber sorgt nur für eine weak Reference auf deinen Subscriber (es wird beim adden in die TList, welche ja nur Pointer aufnimmt, kein _AddRef durchgeführt). Wenn dieser Subscriber somit irgendwo out of scope läuft und (sofern du natürlich das automatische Refcounting von TInterfacedObject z.B. benutzt) freigegeben wird, hängt in deiner Subscriber Liste ein dangling Pointer und beim nächsten Zugriff darauf (z.B. durch MessageAllSubscribers) knallts.
|
AW: Interfaces Generics
Okay ich habe scheinbar die IInterfaces noch nicht ganz verstanden.
Hier ist mein Konzept:
Delphi-Quellcode:
Hier sind ein paar konkrete Klassen:type TNewspaper = class private FTitle : String; procedure SetTitle(const Value : String); public property Title : String read FTitle write SetTitle; end; ISubscriber = interface procedure GetNewspaper(Newspaper : TNewspaper); end; TPublisher = class protected Subscribers : TList<ISubscriber>; public constructor Create; procedure AddSubscriber(Subscriber : ISubscriber); virtual; abstract; procedure RemoveSubscriber(Subscriber : ISubscriber); virtual; abstract; procedure SendNewsToAllSubs; virtual; abstract; end;
Delphi-Quellcode:
type TFAZ = class(TPublisher) private FCurrentNewspaper : TNewspaper; procedure SetCurrentNewspaper(const Value: TNewspaper); function GetCurrentNewspaper : TNewspaper; public procedure AddSubscriber(Subscriber : ISubscriber); override; procedure RemoveSubscriber(Subscriber : ISubscriber); override; procedure SendNewspaperToAllSubs; property CurrentNewspaper : TNewspaper read GetCurrentNewspaper write SetCurrentNewspaper; end; TFischer = class(TInterfacedObject, ISubscriber) procedure GetNewspaper(Newspaper : TNewspaper); end; TMeier = class(TInterfacedObject, ISubscriber) procedure GetNewspaper(Newspaper : TNewspaper); end; Zitat:
Wie verwalte ich denn dann korrekter Weise meine Referenzen? Gibt es die Möglichkeit mir den Referenzzähler der Interface-Klasse zunutzen zu machen? Ist sowas sogar so gedacht? Wie würde ich das denn machen? Grüße |
AW: Interfaces Generics
Zitat:
|
AW: Interfaces Generics
Zitat:
Daher ist auch eine TList<TFoo> und TList<IFoo> binär inkompatibel, weil für Objekte und Interfaces unterschiedlicher Code generiert wird, obwohl es naiv gesagt beides nur Listen sind, die nen Pointer speichern. Zitat:
Konkret zum Thema hier: Benutz zum Speichern deiner Subscriber TList<ISubscriber>. Ob die Klassen, welche ISubcriber implementieren, Refcounting haben oder nicht, ist dann erstmal irrelevant. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:03 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