AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

vererbende Klasse oder Interface? oder beides?

Ein Thema von Vis · begonnen am 24. Okt 2013 · letzter Beitrag vom 28. Okt 2013
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Vis
Vis

Registriert seit: 26. Apr 2013
26 Beiträge
 
Delphi XE8 Professional
 
#1

vererbende Klasse oder Interface? oder beides?

  Alt 24. Okt 2013, 14:30
Hallo. Ich bin gerade am kämpfen/lernen mit Vererbung und Interfaces und bräuchte da mal eine kompetente Meinung.

Meine Problemstellung:
Ich habe verschiedene Messgeräte die ich über GPIB anspreche. Das Schreiben/Lesen ist bei den Messgeräten unterschiedlich. Deshalb wollte ich ein Interface ISchreibenLesen verwenden, dessen Methoden dann jede Klasse implementieren muss. Theoretisch könnte ich ja aber auch abstrakte Methoden in der Oberklasse deklarieren und diese dann jeweils in der Unterklasse überschreiben. Kann man da sagen was besser ist?
Die Oberklasse hatte ich mir gedacht, da ja alle Messgeräte gewisse gemeinsame Felder besitzen (Adresse usw.)

TMessgeräte = class ((TInterfacedObject))

TMessgerätA = class (TMessgeräte, ISchreibenLesen) TMessgerätB = class (TMessgeräte, ISchreibenLesen)


Und noch eine Frage. Die Messgeräte sollen eine Property Range bekommen (mit Getter und Setter).
In der Oberklasse deklariert, wird die Property an die Unterklassen vererbt, die Getter/Setter müssten dann abstract sein. Oder anders, die Property im Interface deklarieren (hier auch Getter/Setter). Dann muss ich in der Unterklasse aber wieder eine Property deklarieren, das wird irgendwie doch nicht mehr so übersichtlich.

Wie würdet ihr sowas machen? Wie gesagt, bin da noch stark am Anfang mit Interfaces und Vererbung und für jede Anregung dankbar.

Grüße
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.048 Beiträge
 
Delphi 12 Athens
 
#2

AW: vererbende Klasse oder Interface? oder beides?

  Alt 24. Okt 2013, 15:04
Ob besser oder schlechter kann man hier nicht sagen. Das kommt wesentlich auf den Rest der Anwendung an. Interfaces bieten Referenzzählung, blähen den Code aber auch etwas auf. Wenn du alles auf einen gemeinsamen Vorfahren zurückführen kannst, ist eine abstrakte Klasse auch keine schlechte Wahl.

Die Getter und Setter kannst du problemlos als abstract deklarieren. Die abgeleitete Klasse braucht dann auch nicht das Property nochmal zu deklarieren - es genügt, wenn die Getter und Setter überschrieben werden.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von romankassebaum
romankassebaum

Registriert seit: 11. Jun 2011
21 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#3

AW: vererbende Klasse oder Interface? oder beides?

  Alt 24. Okt 2013, 20:44
Hallo,

Interfaces bieten zwei grundlegende Vorteile:

1. Durch die Referenzzählung müssen Sie nicht explizit freigegeben werden.
2. Ein Interface kann von verschiedenen Objekten implementiert werden, die gerade nicht über einen gemeinsamen Vorfahren verfügen.

Da Du in Deinem Beispiel den gemeinsamen Vorfahren TMessgerät hast, denke ich, dass Du keine Interfaces benötigst.

In Deinem Beispiel kannst Du übrigens bereits das TMessgerät mit dem Interface ISchreibenLesen verbinden, da die Erben es ohnehin bereitstellen sollen.

--
Viele Grüße,

Roman Kassebaum
Embarcadero Technology Partner
Embarcadero MVP
Blog: http://blog.kassebaum.eu
Roman Kassebaum
  Mit Zitat antworten Zitat
Benutzerbild von Vis
Vis

Registriert seit: 26. Apr 2013
26 Beiträge
 
Delphi XE8 Professional
 
#4

AW: vererbende Klasse oder Interface? oder beides?

  Alt 25. Okt 2013, 07:49
Ok, Danke. Das war schon mal sehr interessant.

Wenn ich das Interface ISchreibenLesen mit der Oberklasse TMessgeräte verbinde, dann müsste ich doch eigentlich die Methoden auch in TMessgeräte implementieren. Das möchte ich ja aber erst in den abgeleiteten Klassen. Also müsste ich ja folglich die vom Interface bereitgestellten Methoden als abstract deklarieren. In meinem Fall ist das vielleicht zuviel des Guten und ich deklariere die Methoden gleich in TMessgeräte ohne das Interface. Ansonsten wäre ja 3-mal eine Methode deklariert (im Interface, Oberklasse, Unterklasse) + die Implementierung. Das kann schon auch unübersichtlich werden.

Werd mich mal ran machen das umzusetzen!
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.114 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: vererbende Klasse oder Interface? oder beides?

  Alt 25. Okt 2013, 10:27
Genau das gefällt mir auch nicht wirklich. Die Schuld liegt da irgendwie eher an der Delphi-Sprache selber, "echte" abstrakte Klassen kennt es nicht.

Delphi-Quellcode:
   INeustartbar = interface
   ['{C952DFE2-65A3-48A4-8681-81F97946DB5A}']
      procedure restart();
   end;

   ISchreibenLesen = interface
   ['{DBAF7078-C915-471F-8C37-F679253220BE}']
      procedure writeStuff();
      procedure readStuff();
   end;
                                                                  (
   AMessgerät = class abstract(TInterfacedObject, ISchreibenLesen)
      public // Warum ist das hier überhaupt notwendig?
         procedure readStuff; virtual; abstract;
         procedure writeStuff; virtual; abstract;
   end;

   TMessgerät1 = class(AMessgerät)
      procedure spezialKram();
   end;

   TMessgerät2 = class(AMessgerät, INeustartbar)
      public
         procedure spezialKram();
         procedure restart();
   end;
  Mit Zitat antworten Zitat
Benutzerbild von romankassebaum
romankassebaum

Registriert seit: 11. Jun 2011
21 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#6

AW: vererbende Klasse oder Interface? oder beides?

  Alt 25. Okt 2013, 22:27
Ich hatte ja gestern schon gesagt, dass man Interfaces sehr gut nutzen kann, um Objekte, die keinen gemeinsamen Vorfahren habe, anzusprechen.
Für die zweite Aufgabe, die Referenzzählung, kann man übrigens auch einen ObjGuard (http://blog.kassebaum.eu/?p=87) nehmen.

Was mir an der vorgestellten Lösung überhaupt nicht gefällt, ist, dass man von TInterfacedObject ableiten muss. Dadurch "weiß" TMessgerät bereits, dass die abgeleiteten Klassen Interfaces nutzen werden.

Ich würde also die Interfaces weglassen.

--
Roman Kassebaum
Embarcadero Technology Partner
Embarcadero MVP
Blog: http://blog.kassebaum.eu
Roman Kassebaum
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.367 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: vererbende Klasse oder Interface? oder beides?

  Alt 26. Okt 2013, 08:33
Delphi-Quellcode:
   INeustartbar = interface
   ['{C952DFE2-65A3-48A4-8681-81F97946DB5A}']
     procedure restart();
   end;

   ISchreibenLesen = interface
   ['{DBAF7078-C915-471F-8C37-F679253220BE}']
     procedure writeStuff();
     procedure readStuff();
   end;
                                                                  
   TMessgerät = class abstract(TInterfacedObject)
   end;

   TMessgerät1 = class(TMessgerät, ISchreibenLesen)
     procedure readStuff;
     procedure writeStuff;
     procedure spezialKram();
   end;

   TMessgerät2 = class(TMessgerät, ISchreibenLesen, INeustartbar)
   public
     procedure readStuff;
     procedure writeStuff;
     procedure spezialKram();
     procedure restart();
   end;
Das geht genauso. Das Interface muss man ja nicht in der Oberklasse angeben.
Delphi-Quellcode:
var
  a: TMessgerät;
  b: ISchreibenLesen;
begin
  a := TMessgerät2.Create;
  b := a as ISchreibenLesen;
  b.readStuff;
end;
(Wobei das Objekt nach der Methode durch das Interface freigegeben wird.)

// EDIT:
Was mir an der vorgestellten Lösung überhaupt nicht gefällt, ist, dass man von TInterfacedObject ableiten muss. Dadurch "weiß" TMessgerät bereits, dass die abgeleiteten Klassen Interfaces nutzen werden.
Warum muss man? Man kann die notwendigen Methoden (QueryInterface, ...) auch in den Unterklassen implementieren. Ich halte das nicht für sinnvoll, kann man aber. Man verliert dann aber die Möglichkeit von der Oberklasse auf das Interface zu casten.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!

Geändert von jaenicke (26. Okt 2013 um 08:36 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Vis
Vis

Registriert seit: 26. Apr 2013
26 Beiträge
 
Delphi XE8 Professional
 
#8

AW: vererbende Klasse oder Interface? oder beides?

  Alt 28. Okt 2013, 09:44
[DELPHI]
Delphi-Quellcode:
var
  a: TMessgerät;
  b: ISchreibenLesen;
begin
  a := TMessgerät2.Create;
  b := a as ISchreibenLesen;
  b.readStuff;
end;
(Wobei das Objekt nach der Methode durch das Interface freigegeben wird.)
Ein solcher Aufruf ist mir noch nicht geläufig. Wo liegt der Unterschied wenn ich stattdessen mit dem Objekt a arbeite? Also a.readStuff.


@sx2008
Also der Datentransport ist schon in ein eigenen Klasse mit direktem Zugriff auf den GPIB-Bus.
Delphi-Quellcode:
procedure send (addr : integer; s : AnsiString; var status : integer);
procedure enter (var s : Ansistring; maxlen : word; var len : word;
                       addr : integer; var status : integer);

procedure ieee488_send (addr : longint; c : Pointer; len : longint; var status : longint) stdcall;
        external 'IEEE_32M.DLLname 'IEEE488_SEND';
procedure ieee488_enter (c : Pointer; maxlen : longint; var len : longint;
                 addr : longint; var status : longint) stdcall;
Also diese Klasse TGPIB weiß auch nichts von anderen Klassen.

Nur sind eben die Befehle für die Messgeräte unterschiedlich, z.B. Agilent und Keithley.
Delphi-Quellcode:
procedure send (22, 'ID?', status); //Agilent
procedure send (22, 'IDN?', status); //Keithley
Für jede Unterklasse muss man also fast alle Methoden implementieren. Den Vorteil den ich sehe, ist dass man einmal Methodennamen festlegt (auf Höhe der abstrakten TMessgeräte-Klasse), die dann immer wieder gebraucht werden und man so eine einheitliche Syntax über alle Messgeräte hat.

Vergleichen kann man das vielleicht mit der IVIDmm Klasse zur Ansteuerung von Messgeräten. Die besitzt auch ganz allgemeine Methoden Initialize, Close, Configure und Propertys Measurement.Read usw. Was am Ende für ein Messgerät dran hängt ist egal.

Ob es sich bei mir wirklich so allgemeingültig durchführen lässt, bin ich gerade am probieren.
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#9

AW: vererbende Klasse oder Interface? oder beides?

  Alt 28. Okt 2013, 10:05
Nur sind eben die Befehle für die Messgeräte unterschiedlich, z.B. Agilent und Keithley.
Delphi-Quellcode:
procedure send (22, 'ID?', status); //Agilent
procedure send (22, 'IDN?', status); //Keithley
Für jede Unterklasse muss man also fast alle Methoden implementieren.
Muss man nicht unbedingt wenn der Unterschied nur in der Schreibweise der Befehle liegt.

In der Basisklasse führst du eine virtuelle Funktion ein die eine Kennung in einen Befehl umsetzt:
Delphi-Quellcode:
const
  QUERYSTATUS = 1;
  RESETDEVICE = 2;
  // usw.

function TMessgeraet.GetCommandString(commandid:Integer):string; // virtual, protected
begin
  raise Exception.CreateFmt('command %d not implemented (%s)', [commandid, Classname]);
end;

function TMessgeraetAgilent.GetCommandString(commandid:Integer):string; // override;
begin
  case commandid of
    QUERYSTATUS: Result := 'ID?';
    RESETDEVICE: Result := ...;
  else
    result := inherited GetCommandString(commandid);
end;
Anstelle der Konstanten kann man auch einen Aufzählungstyp verwenden.
fork me on Github
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.367 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: vererbende Klasse oder Interface? oder beides?

  Alt 28. Okt 2013, 10:07
Ein solcher Aufruf ist mir noch nicht geläufig. Wo liegt der Unterschied wenn ich stattdessen mit dem Objekt a arbeite? Also a.readStuff.
Man braucht für die Initialisierung kein weiteres Interface und muss diese Funktionalität auch nicht nach außen veröffentlichen. Danach packt man das Objekt in eine Interfacevariable und aktiviert damit die Referenzzählung.

Dieses Interface kann dann auf die zur Initialisierung notwendigen Routinen nicht zugreifen und es gibt auch kein anderes Interface, auf das man dafür casten könnte.

Theoretisch kann man auch hinterher noch auf den Objekttyp casten, sofern man sich im gleichen Modul der Anwendung befindet (selbe Exe, selbe DLL, ..), aber das sollte bei sauberer Implementierung aller Schnittstellen nicht notwendig sein.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 10:07 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz