AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Vererbung: Wie rufe ich Klasse.Parent.Methode auf?
Thema durchsuchen
Ansicht
Themen-Optionen

Vererbung: Wie rufe ich Klasse.Parent.Methode auf?

Ein Thema von MaBuSE · begonnen am 23. Okt 2014 · letzter Beitrag vom 27. Okt 2014
Antwort Antwort
Benutzerbild von sx2008
sx2008

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

AW: Vererbung: Wie rufe ich Klasse.Parent.Methode auf?

  Alt 24. Okt 2014, 23:50
Ich denke du solltest dir mal das Liskovsches Substitutionsprinzip anschauen.
Verkürzt gesagt muss es jederzeit möglich sein an eine Klasse durch eine davon abgeleitete Klasse zu ersetzen.
Delphi-Quellcode:
// der Procedure muss es egal sein ob "myobject" vom Typ TBasisKlasse oder von einer davon abgeleiteten Klasse ist
procedure Machwas(TBasisKlasse: myobject);
begin
Dies ist auch der Grund dafür weshalb man in abgleiteten Klassen keine Properties oder Methoden entfernen kann.
Auch darf man die Sichtbarkeit (z.B. von public auf private) nicht einschränken.
Das Überdecken einer virtuellen Methode mit reintroduce ist ein ganz klares Pfui.

Häufig lassen sich Designprobleme lösen indem man virtuelle Methoden nicht public sondern nur protected macht:
Delphi-Quellcode:
TBaseclass = class(TObject)
protected
   procedure Internal_A(x: Boolean); virtual;
public
   procedure A(x: Boolean);
    
...
procedure TBaseclass.A(x: Boolean);
begin
    // code vorher
    // die Basisklasse kann hier sogar entscheiden ob sie Internal_A() überhaupt aufrufen möchte
    Internal_A(x); // virtuelle Methode aufrufen
    // code danach (Exceptionhandling, Logging, was auch immer)
end;
Diese Vorgehensweise ist auch als template method pattern bekannt.
fork me on Github
  Mit Zitat antworten Zitat
Benutzerbild von ChrisE
ChrisE

Registriert seit: 15. Feb 2006
Ort: Hechingen
504 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: Vererbung: Wie rufe ich Klasse.Parent.Methode auf?

  Alt 27. Okt 2014, 06:42
Hallo MaBuSE,

@Chris: Das geht leider nicht, da ich das alte Verhalten ja durchaus wünsche, wenn (True) übergeben wurde. Außerdem sollte man wenn man es so macht das Schlüsselwort reintreduce verwenden um zu dokumentieren, dass man genau das machen möchte und nicht aus versehen virtual/override vergessen hat.
reintroduce bin ich zu 100% bei dir. Der Quelltext funktioniert aber tatsächlich, wenn du es so machst - zumindest bei mir XE5.

Delphi-Quellcode:
  TMutter = class(TObject)
  public
    procedure a(x: Boolean); virtual;
    procedure b;
  end;

  TKind = class(TMutter)
  public
    procedure a(x: Boolean); override;
    procedure b;reintroduce;
  end;

//....


procedure TMutter.a(x: Boolean);
begin
  Log('TMutter.a1');
  if x then
  begin
    // b aufrufen. (Wenn Self = TKind ist, dann wird TKind.b aufgerufen.)
    TKind(Self).b;
  end
  else
  begin
    // Hier sollte immer TMutter.b aufgerufen werden!!!
    TMutter(Self).b;
  end;
  Log('TMutter.a2');
end;
Oder is dir das zu explizit?

Gruß, Chris
Christian E.
Es gibt 10 Arten von Menschen, die die Binär lesen können und die die es nicht können

Delphi programming rules
  Mit Zitat antworten Zitat
Benutzerbild von MaBuSE
MaBuSE

Registriert seit: 23. Sep 2002
Ort: Frankfurt am Main (in der Nähe)
1.840 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Vererbung: Wie rufe ich Klasse.Parent.Methode auf?

  Alt 27. Okt 2014, 10:01
Oder is dir das zu explizit?
Ja
Ich bin Fan von KISS ("keep it stupid simple" oder "So einfach wie möglich, so kompliziert wie nötig")


Die Lösung mit dem internal_procname finde ich gut.
Sie ist vor allem einfacher zu verstehen, wenn man in ein paar Jahren noch mal über die Zeilen stolpert.

Internal_procname hatte ich schon in den protected Abschnitt gesetzt, bevor ich die Nachricht von sx2008 las.

Ich habe das mit dem internal_procname auch schon früher gemacht, aber aus irgendeinem Grund habe ich mich diesmal in dem Problem festgefahren. Man sieht den Wald vor lauter Bäumen nicht. Normalerweise finde ich die Lösung dann beim Erstellen des Beispielprogramms, diesmal nicht
Da ist es gut, wenn man von der DP einen Schups in die richtige Richtung bekommt.


Danke für alle Antworten.
MaBuSE
(°¿°) MaBuSE - proud to be a DP member
(°¿°) MaBuSE - proud to be a "Rüsselmops" ;-)

Geändert von MaBuSE (27. Okt 2014 um 10:04 Uhr)
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#4

AW: Vererbung: Wie rufe ich Klasse.Parent.Methode auf?

  Alt 27. Okt 2014, 12:21
Delphi-Quellcode:
...
procedure TMutter.a(x: Boolean);
begin
...
  TKind(Self).b;
...
Schwerer Fehler.
1. Woher soll die Mutter wissen, das es ein Kind gibt?
2. Welche Methode soll aufgerufen werden, wenn es noch eine Ableitung der TMutter (oder von TKind) gibt?
3. Wenn die Mutter wissen muss, das es genau das eine Kind gibt, wozu dann zwei Klassen?

Mach es so, wie Uwe vorgeschlagen hat. Die Mutter ruft entweder explizit die eigene Methode oder aber die virtuelle Methode auf. So ist es OOP-konform und auch sauber.
  Mit Zitat antworten Zitat
Benutzerbild von MaBuSE
MaBuSE

Registriert seit: 23. Sep 2002
Ort: Frankfurt am Main (in der Nähe)
1.840 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Vererbung: Wie rufe ich Klasse.Parent.Methode auf?

  Alt 27. Okt 2014, 13:45
Delphi-Quellcode:
...
procedure TMutter.a(x: Boolean);
begin
...
  TKind(Self).b;
...
Schwerer Fehler.
1. Woher soll die Mutter wissen, das es ein Kind gibt?
Delphi-Quellcode:
...
  if Self is TKind then (Self as TKind).b;
...
2. Welche Methode soll aufgerufen werden, wenn es noch eine Ableitung der TMutter (oder von TKind) gibt?
In diesem Fall würde automatisch die von TMutter aufgerufen.
Da sie ja nicht mit reintreduce überschrieben wurde.

3. Wenn die Mutter wissen muss, das es genau das eine Kind gibt, wozu dann zwei Klassen?
Das ist die Schwachstelle. Dann wird es umständlich.
Delphi-Quellcode:
...
  if Self is TLieblingsKind then
  begin
   (Self as TLieblingsKind).b
  end
  else
  begin
    if Self is TStiefKind then
    begin
      (Self as TStiefKind).b
    end
    else
    begin
      // Mutterschaftstest durchführen.

      // Den Vorteil, den Mütter haben ist,
      // das sie in der Regel wissen, dass es ihre Kinder sind.
    end;
  end;
...
Aber wahrscheinlich gibt es dafür auch einen einfacheren Weg.

Fakt ist, das die Mutter alle Kinder (und Kindes-Kinder), die eine Sonderbehandlung benötigen, kennen muss.
Das icht schlecht.
Das ist bei der internal_proc Lösung nicht der Fall.

Mach es so, wie Uwe vorgeschlagen hat. Die Mutter ruft entweder explizit die eigene Methode oder aber die virtuelle Methode auf. So ist es OOP-konform und auch sauber.
Ich habe es wie Uwe gemacht.
Wenn du meine Texte gelesen hättest, wüsstest Du wie ich darüber denke.
(°¿°) MaBuSE - proud to be a DP member
(°¿°) MaBuSE - proud to be a "Rüsselmops" ;-)
  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 06:09 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