AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Interface und Objektreferenz offenbar noch nicht verstanden
Thema durchsuchen
Ansicht
Themen-Optionen

Interface und Objektreferenz offenbar noch nicht verstanden

Ein Thema von Hepdepaddel · begonnen am 18. Sep 2015 · letzter Beitrag vom 30. Sep 2015
Antwort Antwort
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.083 Beiträge
 
Delphi 10.4 Sydney
 
#1

AW: Interface und Objektreferenz offenbar noch nicht verstanden

  Alt 18. Sep 2015, 10:22
Delphi-Quellcode:
  IPlanDataEnumerator = Interface
  ['{BDB4BEB2-FFE4-429A-9007-4DA7D235E92A}']
    procedure HandlePlanDataElement(PD: TPlanData);
    procedure Init; // <--- falls alle anderen Klassen das auch brauchen, ansonsten in das entsprechende Interface verschieben
  End;

ISummary = interface(IPlanDataEnumerator)
[Irgendeine_GUID]
  function GetCountUnassignedOrderPackages : Integer;
  function GetCountUnassignedOrders : Integer;
  property CountUnassignedOrderPackages : Integer read GetCountUnassignedOrderPackages;
  property CountUnassignedOrders : Integer read GetCountUnassignedOrders;
end;
Delphi-Quellcode:
TMySummary = class(TInterfacedObject, IPlanDataEnumerator, ISummary)
...
Delphi-Quellcode:
var
  Summary: ISummary ;
begin
  Summary := TMySummary.Create;
  Summary.Init;
  ProjectData.CallEnumeratorForAllElements(Summary);
  StatusBar.Panels[1].Text:='Unassigned Order Packages: '+IntToStr(Summary.CountUnassignedOrderPackages);
  StatusBar.Panels[2].Text:='Unassigned Orders: '+IntToStr(Summary.CountUnassignedOrders);
end;
Viel Spaß!
  Mit Zitat antworten Zitat
alda

Registriert seit: 24. Mär 2014
Ort: Karlsruhe
93 Beiträge
 
Delphi XE6 Architect
 
#2

AW: Interface und Objektreferenz offenbar noch nicht verstanden

  Alt 18. Sep 2015, 12:51
Ein paar Regeln die es zu beachten gibt:
1. Ein referenzgezähltes Objekt ist referenzgezählt. Es wird niemals manuell destroyed (Aufruf von .Free), es wird dann automatisch destroyed , wenn es keine Referenzen mehr auf das Objekt gibt.
2. Eine Variable für ein referenzgezähltes Objekt ist immer vom Typ eines der von der Klasse implementierten Interfaces (entweder ISummary oder IPlanDataEnumerator) und niemals von der Klasse (TMySummary) selbst.
3. Es dürfen nur die Instanzmethoden aufgerufen werden, die über ein entsprechendes Interface definiert wurden (ISummary oder IPlanDataEnumerator) und niemals Instanzmethoden die ausschließlich über die implementierende Klasse bereitgestellt (TMySummary), aber in keinem der implementierten Interfaces definiert sind. Einzige Ausnahme sind Aggregated & Contained Objects

Geändert von alda (18. Sep 2015 um 13:05 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Hepdepaddel
Hepdepaddel

Registriert seit: 12. Dez 2005
Ort: Bremen
91 Beiträge
 
Delphi 2006 Enterprise
 
#3

AW: Interface und Objektreferenz offenbar noch nicht verstanden

  Alt 18. Sep 2015, 14:18
Erst einmal vielen Dank für die bisherigen Ratschläge! Hier noch die Deklaration von TMySummary

Delphi-Quellcode:
  TMySummary = class(TInterfacedObject, IPlanDataEnumerator)
    public
      CountUnassignedOrderPackages, CountUnassignedOrders: Integer;
      procedure Init;
      procedure HandlePlanDataElement(PD: TPlanData);
  end;
Und hier die Implementierung:

Delphi-Quellcode:
procedure TMySummary.Init;
begin
  Self.CountUnassignedOrderPackages:=0;
  Self.CountUnassignedOrders:=0;
end;


procedure TMySummary.HandlePlanDataElement(PD: TPlanData);
begin
  if PD.IsOrderPackage then begin
    if TOrderPackage(PD).LPOCostType='then Inc(Self.CountUnassignedOrderPackages);
  end;
  if PD.IsOrder then begin
    if TOrder(PD).SAPCostType='then Inc(Self.CountUnassignedOrders);
  end;
end;

Den Ansatz mit zwei Interfaces werde ich nachher gleich mal probieren, wobei ich erstaunt bin, dass man ein ISummary definieren kann und das dann als IPlanEnumerator übergeben kann.
  Mit Zitat antworten Zitat
Benutzerbild von Hepdepaddel
Hepdepaddel

Registriert seit: 12. Dez 2005
Ort: Bremen
91 Beiträge
 
Delphi 2006 Enterprise
 
#4

AW: Interface und Objektreferenz offenbar noch nicht verstanden

  Alt 18. Sep 2015, 14:36
Hi,

der Ansatz mit zwei Interfaces funktioniert leider nicht. Da beschwert sich der Compiler verständlicherweise über inkompatible Typen (ISummary und IPlanDataEnumerator).

Delphi-Quellcode:

TMySummary = class(TInterfacedObject, IPlanDataEnumerator, ISummary)
(...)


procedure Tfrm_Main.UpdateStatusBar;
var
  Summary: ISummary;
begin
  Summary:=TMySummary.Create;
  Summary.Init;
  ProjectData.CallEnumeratorForAllElements(Summary); // <<<<< Hier wird ISummary als IPlanDataEnumerator übergeben
  StatusBar.Panels[1].Text:='Unassigned Order Packages: '+IntToStr(Round(Summary.GetSummaryResult));
end;
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.083 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Interface und Objektreferenz offenbar noch nicht verstanden

  Alt 18. Sep 2015, 14:51
der Ansatz mit zwei Interfaces funktioniert leider nicht. Da beschwert sich der Compiler verständlicherweise über inkompatible Typen (ISummary und IPlanDataEnumerator).
Hast du ISummary von IPlanDataEnumerator abgeleitet?
  Mit Zitat antworten Zitat
alda

Registriert seit: 24. Mär 2014
Ort: Karlsruhe
93 Beiträge
 
Delphi XE6 Architect
 
#6

AW: Interface und Objektreferenz offenbar noch nicht verstanden

  Alt 18. Sep 2015, 15:08
der Ansatz mit zwei Interfaces funktioniert leider nicht. Da beschwert sich der Compiler verständlicherweise über inkompatible Typen (ISummary und IPlanDataEnumerator).
Eine Klasse kann beliebig viele Interfaces implementieren, das geht schon. Wenn die Interfaces nicht voneinander ableiten und ein impliziter Cast nicht möglich ist, dann musst Du das explizit casten (AS). Allerdings sollte man auch mal schaun ob deine Implementierung insgesamt so Sinn macht.
  Mit Zitat antworten Zitat
Benutzerbild von Hepdepaddel
Hepdepaddel

Registriert seit: 12. Dez 2005
Ort: Bremen
91 Beiträge
 
Delphi 2006 Enterprise
 
#7

AW: Interface und Objektreferenz offenbar noch nicht verstanden

  Alt 18. Sep 2015, 17:06
Ist ja voneinander abgeleitet!
Argh... gucken müsste man können. Freitag, wird Zeit fürs Wochenende.

Das funktioniert jetzt auch so:

Delphi-Quellcode:
procedure Tfrm_Main.UpdateStatusBar;
var
  Summary: IPlanDataEnumerator;
begin
  Summary:=TMySummary.Create;
  TMySummary(Summary).Init;
  ProjectData.CallEnumeratorForAllElements(Summary);
  StatusBar.Panels[1].Text:='Unassigned Order Packages: '+IntToStr(TMySummary(Summary).CountUnassignedOrderPackages);
  StatusBar.Panels[2].Text:='Unassigned Orders: '+IntToStr(TMySummary(Summary).CountUnassignedOrders);
end;
Aber die Variante mit einem spezielleren Enumerator-Interface ist natürlich sauberer. Werde ich nochmal so umsetzen. Die Umsetzung oben gefällt mir nicht wirklich, ist ein wenig so wie eine unverputzte Hauswand.
  Mit Zitat antworten Zitat
Benutzerbild von Hepdepaddel
Hepdepaddel

Registriert seit: 12. Dez 2005
Ort: Bremen
91 Beiträge
 
Delphi 2006 Enterprise
 
#8

AW: Interface und Objektreferenz offenbar noch nicht verstanden

  Alt 18. Sep 2015, 17:07
Und an alle: Besten Dank!
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.083 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Interface und Objektreferenz offenbar noch nicht verstanden

  Alt 21. Sep 2015, 10:04
Delphi-Quellcode:
procedure Tfrm_Main.UpdateStatusBar;
var
  Summary: IPlanDataEnumerator;
begin
  Summary:=TMySummary.Create;
  TMySummary(Summary).Init;
  ProjectData.CallEnumeratorForAllElements(Summary);
  StatusBar.Panels[1].Text:='Unassigned Order Packages: '+IntToStr(TMySummary(Summary).CountUnassignedOrderPackages);
  StatusBar.Panels[2].Text:='Unassigned Orders: '+IntToStr(TMySummary(Summary).CountUnassignedOrders);
end;
Warum machst du das jetzt so?
Das harte casten auf die Klasse ist suboptimal.
Wenn du möchtest, dass ein klarer(er) Bezug zu IPlanDataEnumerator besteht kannst du es auch so schreiben:
Delphi-Quellcode:
procedure Tfrm_Main.UpdateStatusBar;
var
  Summary: ISummary;
begin
  Summary:=TMySummary.Create;
  Summary.Init;
  ProjectData.CallEnumeratorForAllElements(Summary as IPlanDataEnumerator ); // <<<<< Hier wird ISummary als IPlanDataEnumerator übergeben
  StatusBar.Panels[1].Text:='Unassigned Order Packages: '+IntToStr(Round(Summary.GetSummaryResult));
end;
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.083 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Interface und Objektreferenz offenbar noch nicht verstanden

  Alt 18. Sep 2015, 14:47
Den Ansatz mit zwei Interfaces werde ich nachher gleich mal probieren, wobei ich erstaunt bin, dass man ein ISummary definieren kann und das dann als IPlanEnumerator übergeben kann.
Ist ja voneinander abgeleitet!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:48 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