Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Instanz von T wird mit der abstrakten Methode XYZ angelegt (https://www.delphipraxis.net/195698-instanz-von-t-wird-mit-der-abstrakten-methode-xyz-angelegt.html)

Codehunter 19. Mär 2018 09:34

Delphi-Version: 10.2 Tokyo

Instanz von T wird mit der abstrakten Methode XYZ angelegt
 
Hallo!

Ich bekomme ein paar Compilerwarnungen der Art
Code:
Instanz von T wird mit der abstrakten Methode XYZ angelegt
Das ist soweit nicht dramatisch, weil die betreffende Klasse diese Methoden tatsächlich nicht benötigt. Mich würde aber interessieren ob es eine elegantere Möglichkeit gibt, diese Compilerwarnung zu beseitigen als leere Dummy-Prozeduren in den implementation-Abschnitt zu schreiben.

Grüße
Cody

Uwe Raabe 19. Mär 2018 09:51

AW: Instanz von T wird mit der abstrakten Methode XYZ angelegt
 
Zitat:

Zitat von Codehunter (Beitrag 1396577)
Mich würde aber interessieren ob es eine elegantere Möglichkeit gibt, diese Compilerwarnung zu beseitigen als leere Dummy-Prozeduren in den implementation-Abschnitt zu schreiben.

Ja, überarbeite dein Design so, daß die Methode erst in der Ableitungshierarchie deklariert wird, wo sie gebraucht wird. Wenn sie dort immer noch abstrakt sein muss, dann stelle sicher, daß keine Instanz dieser abstrakten Klasse erstellt wird.

himitsu 19. Mär 2018 09:52

AW: Instanz von T wird mit der abstrakten Methode XYZ angelegt
 
Vor und nach dem Create per Compiler-Befehl die Warnung deaktivieren?

Aber wer sagt dir jetzt, dass in Zukunft diese Methode nicht doch irgendwann mal versucht wird aufzurufen?

Codehunter 19. Mär 2018 10:19

AW: Instanz von T wird mit der abstrakten Methode XYZ angelegt
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1396582)
Ja, überarbeite dein Design so, daß die Methode erst in der Ableitungshierarchie deklariert wird, wo sie gebraucht wird.

Zitat:

Zitat von himitsu (Beitrag 1396583)
Vor und nach dem Create per Compiler-Befehl die Warnung deaktivieren?

Aber wer sagt dir jetzt, dass in Zukunft diese Methode nicht doch irgendwann mal versucht wird aufzurufen?

Wenn ich das beides jetzt zusammen nehme, dann erscheint es mir am sinnvollsten, die betreffende Methode bereits in der Basisklasse nicht mehr abstrakt zu halten sondern dort mit einer leeren Prozedur anzulegen. So habe ich diesen "Dummy" nur einmal und nicht in jeder abgeleiteten Klasse. Mit dem constructor und destructor von TObject verhält es sich ja ganz ähnlich.

mkinzler 19. Mär 2018 10:22

AW: Instanz von T wird mit der abstrakten Methode XYZ angelegt
 
Noch besser nicht Basisklasse, sondern erst in der Hierarchie, wenn benötigt

Codehunter 19. Mär 2018 10:36

AW: Instanz von T wird mit der abstrakten Methode XYZ angelegt
 
Das ist richtig, im konkreten Fall jedoch etwas unpraktikabel, weil es ein Delphi Starter ist. Ich müsste weiter oben in der Hierarchie schon abzweigen und dann jede Menge nachimplementieren. Da ist es deutlich einfacher und sicherer, einfach leere Prozeduren anzulegen. Im ungünstigsten Fall passiert dann einfach gar nichts, aber es kracht nicht mit einer Abstract Exception. Da es sich bei den bisher abstraktion Methoden um Functions handelt, gebe ich einfach den Defaultwert zurück, auf den ich dann in der Routine prüfen kann, wo dynamisch die eine oder andere Kindklasse verwendet wird.

Uwe Raabe 19. Mär 2018 11:06

AW: Instanz von T wird mit der abstrakten Methode XYZ angelegt
 
Wenn du sicher bist, daß die Methoden nur in überschreibenden Klassen verwendet werden, kannst du auch in der Dummy-Methode eine Assertion einbauen oder eine
Delphi-Quellcode:
EAbstractError
-Exception werfen. Dann bekommst du wenigstens mit, wenn sich am Aufrufverhalten ungewollt etwas ändert.

Codehunter 19. Mär 2018 12:25

AW: Instanz von T wird mit der abstrakten Methode XYZ angelegt
 
Da hast du völlig recht Uwe. Die Idee finde ich sogar sehr gut, in der Basisklasse eine Art von Not-Implemented-Benachrichtigung einzubauen. Irgendwie finde ich es schade, dass es neben den protected- und public-Abschnitten in Klassen nicht auch einen gibt wo man Methoden deklarieren kann, die ausschließlich in Kindklassen angesprochen/überschrieben werden können und deren Sichtbarkeit nach außen hin in Kindklassen nicht erhöht werden kann. Also ungefähr sowas:
Delphi-Quellcode:
type
  TMyBaseClass = class(TObject)
  private

  protected

  descendend
    procedure MyMethod; virtual; obligatory;
  public

  end;

  TMyChildClass = class(TMyBaseClass)
  descended
    procedure MyMethod; override; // <-- Klappt
  end;

  TMyChildClass2 = class(TMyBaseClass)
  public
    procedure MyMethod; override; // <-- Compilerfehler wegen erhöhter Sichtbarkeit
  end;

  TMyChildClass3 = class(TMyBaseClass)
  descendend
    // MyMethod wird nicht implementiert, Compilerfehler
  end;
Damit könnte man von vornherein ausschließen, dass solche Methoden nach außen hin sichtbar werden. Ein Konstrukt aus protected Methode + final trifft das irgendwie nicht so richtig. Das Statement "obligatory" würde die Implementierung einer Methode in Kindklassen erzwingen - "abstract" lässt es ja offen und im Zweifel kracht es.

Uwe Raabe 19. Mär 2018 12:32

AW: Instanz von T wird mit der abstrakten Methode XYZ angelegt
 
Zitat:

Zitat von Codehunter (Beitrag 1396608)
Irgendwie finde ich es schade, dass es neben den protected- und public-Abschnitten in Klassen nicht auch einen gibt wo man Methoden deklarieren kann, die ausschließlich in Kindklassen angesprochen/überschrieben werden können.

Es gibt
Delphi-Quellcode:
strict protected
.

Codehunter 19. Mär 2018 12:37

AW: Instanz von T wird mit der abstrakten Methode XYZ angelegt
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1396610)
Es gibt
Delphi-Quellcode:
strict protected
.

Tatsache :) Da wird man alt wie eine Kuh und lernt immer noch dazu... Gibts vielleicht auch sowas wie das "obligatory" in meinem Beispiel?

Uwe Raabe 19. Mär 2018 15:03

AW: Instanz von T wird mit der abstrakten Methode XYZ angelegt
 
Zitat:

Zitat von Codehunter (Beitrag 1396611)
Gibts vielleicht auch sowas wie das "obligatory" in meinem Beispiel?

Nicht direkt in der Form, aber du kannst in den Projekt-Optionen unter Hinweise und Warnungen bei der Warnung Konstruierende Instanz enthält abstrakte Methode den Eintrag auf Fehler stellen, dann compiliert der Source so nicht mehr.

Codehunter 19. Mär 2018 17:33

AW: Instanz von T wird mit der abstrakten Methode XYZ angelegt
 
Hmmm womit wir wieder beim abstract wären :-D Aber ich meine mich zu erinnern, dass das früher bei D7 von Haus aus so war, dass der Compiler abgebrochen hat wenn Abstracts nicht implementiert waren. Mit dem strict protected bin ich aber schon mal ein gutes Stück weiter beim ordentlichen Anwendungsdesign.

Zacherl 19. Mär 2018 17:41

AW: Instanz von T wird mit der abstrakten Methode XYZ angelegt
 
Zitat:

Zitat von Codehunter (Beitrag 1396660)
Mit dem strict protected bin ich aber schon mal ein gutes Stück weiter beim ordentlichen Anwendungsdesign.

Verwenden meiner Meinung nach eh zu wenige Leute den
Delphi-Quellcode:
strict
Modifier (bin ich auch erst drüber gestoßen, nachdem ich schon Jahrelang mit Delphi gearbeitet habe). Habe mir angewöhnt immer
Delphi-Quellcode:
strict private
und
Delphi-Quellcode:
strict protected
zu verwenden, wenn ich die Felder/Methoden tatsächlich nur intern verwende. Mann nimmt ja auch unter z.B. Java nicht standardmäßig überall die
Delphi-Quellcode:
package
-Privacy.

Fritzew 19. Mär 2018 18:07

AW: Instanz von T wird mit der abstrakten Methode XYZ angelegt
 
Was in dem Zusammenhang fehlt, (meiner Meinung nach) ist das Konzept der friendklassen wie in C++
Dann muss man nicht unbedingt alles public machen was von einer unterstützenden Klasse benötigt wird.
Kleinere Unitfiles, bessere Wartbarkeit



Zitat:

Zitat von Zacherl (Beitrag 1396663)
Zitat:

Zitat von Codehunter (Beitrag 1396660)
Mit dem strict protected bin ich aber schon mal ein gutes Stück weiter beim ordentlichen Anwendungsdesign.

Verwenden meiner Meinung nach eh zu wenige Leute den
Delphi-Quellcode:
strict
Modifier (bin ich auch erst drüber gestoßen, nachdem ich schon Jahrelang mit Delphi gearbeitet habe). Habe mir angewöhnt immer
Delphi-Quellcode:
strict private
und
Delphi-Quellcode:
strict protected
zu verwenden, wenn ich die Felder/Methoden tatsächlich nur intern verwende. Mann nimmt ja auch unter z.B. Java nicht standardmäßig überall die
Delphi-Quellcode:
package
-Privacy.


mkinzler 19. Mär 2018 22:03

AW: Instanz von T wird mit der abstrakten Methode XYZ angelegt
 
Bei Delphi sind alle innerhalb einer Unit "Freunde"

Zacherl 19. Mär 2018 22:06

AW: Instanz von T wird mit der abstrakten Methode XYZ angelegt
 
Zitat:

Zitat von mkinzler (Beitrag 1396707)
Bei Delphi sind alle innerhalb einer Unit "Freunde"

Das stimmt zwar, aber ich kann Fritzw trotzdem nur zustimmen, dass dieses Verhalten "schlechter" ist als die friend-classes unter C++. Bei Delphi ist man genau deshalb nämlich oft gezwungen mehrere Klassen in einer gemeinsamen Unit zu deklarieren, die man ansonsten lieber aufgeteilt hätte. Einzige Alternative ist dann Felder/Methoden
Delphi-Quellcode:
public
zu deklarieren - was noch unschöner ist.

Aber gut, das wird denke ich etwas OT jetzt :stupid:


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:49 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