![]() |
Virtuelle Methode überladen
Moin,
ich habe folgendes Konstrukt:
Delphi-Quellcode:
Beim Compilieren bekomme ich die Warnung: [dcc32 Warnung] Unit7.pas(17): W1010 Methode 'DoSomething' verbirgt virtuelle Methode vom Basistyp 'TClass1'
TClass1 = class
public procedure DoSomething; virtual; end; TClass2 = class(TClass1) public procedure DoSomething(AText : String); overload; end; Ich verstehe nicht, warum das so ist. Die Deklaration von TClass2.DoSomething unterscheidet sich doch von TClass1.DoSomething (es wird ja nur eine Überladung hinzugefügt). Warum wird dann die Methode aus TClass1 verborgen? Und wie kann ich das verhindern? Danke! |
AW: Virtuelle Methode überladen
Überladen wird innerhalb einer Klasse:
Delphi-Quellcode:
Möchtest du die Signatur in einer erbenden Klasse ändern musst du reintroduce benutzen:
TClass1 = class
public procedure DoSomething; virtual; overload procedure DoSomething(AText : String); overload; end;
Delphi-Quellcode:
TClass1 = class
public procedure DoSomething; virtual; end; TClass2 = class(TClass1) public procedure DoSomething(AText : String); reintroduce; // hier wird die Signatur nur geändert aber keine zweite Variante eingeführt procedure DoSomething(AText : String); reintroduce; overload // Hier wird eine zweite Variante definiert; entspricht overload innerhalb einer Klasse end; |
AW: Virtuelle Methode überladen
Zitat:
Wenn das keine rein theoretische Frage ist, dann könnte das ein Hinweis auf ein schlechtes Design sein. Meistens findet man ein 'Workaround', d.h. eine Umformulierung des Codes, der sich im Nachhinein als sauberer herausstellt. Wieso z.B. muss die neue Methode genauso heißen? Macht sie wirklich das Gleiche? @bepe: Ist dann in TClass2 auch 'DoSomething()' bekannt? |
AW: Virtuelle Methode überladen
Falls Du DoSomething nur zusätzlich mit einem Parameter versehen willst, braucht sie nicht virtuell zu sein:
Delphi-Quellcode:
Falls Du später auch noch überladen willst, ist das so möglich:
TClass1 = class
public procedure DoSomething; overload; end; TClass2 = class(TClass1) public procedure DoSomething(AText : String); overload; end;
Delphi-Quellcode:
TClass1 = class
public procedure DoSomething; overload; virtual; end; TClass2 = class(TClass1) public procedure DoSomething(AText : String); overload; end; |
AW: Virtuelle Methode überladen
Vielen Dank für die Erklärung. Mit reintroduce funktioniert es wie gewünscht. Damit wäre meine Frage erledigt.
Jetzt kommt der philosophische Teil, wo über den besten Weg diskutiert werden darf :D Zitat:
Ich könnte sie auch umbenennen, wobei ich mich frage, ob das in diesem Fall sauberer wäre. Hier der "echte" Fall: es geht um die UniDac-Komponenten. Dazu gibt es den Sql-Monitor, der alle Sql-Anfragen, die von den Komponenten Richtung Server geschickt werden, ausgibt. Das ist sehr praktisch für Debuggingzwecke. Die Connection bietet die Methode "MonitorMessage", mit der ich eine eigene Meldung im Sql-Monitor ausgeben kann (auch zu Debugzwecken manchmal hilfreich). Die wollte ich nun mit dem Transactionhandling verbinden:
Delphi-Quellcode:
Was dann entsprechend so implementiert ist:
TmyConnection = class(TUniConnection)
private { Private-Deklarationen } protected { Protected-Deklarationen } public procedure StartTransaction(ASqlMonitorMessage : String); overload; procedure Commit (ASqlMonitorMessage : String); reintroduce; overload; procedure Rollback (ASqlMonitorMessage : String); reintroduce; overload; published { Published-Deklarationen } end;
Delphi-Quellcode:
nun kann ich in TmyConnection.StartTransaction/Commit/Rollback einen eigenen Text mitgeben, der für die Fehlersuche (insbesondere beim Kunden, wo ich kein Delphi installiert hab) hilfreich sein soll.
procedure TmyConnection.Commit(ASqlMonitorMessage: String);
begin MonitorMessage('<< Committing Transaction: ' + ASqlMonitorMessage); Commit; end; procedure TmyConnection.Rollback(ASqlMonitorMessage: String); begin MonitorMessage('!! Rolling back Transaction: ' + ASqlMonitorMessage); Rollback; end; procedure TmyConnection.StartTransaction(ASqlMonitorMessage: String); begin MonitorMessage('>> Starting Transaction: ' + ASqlMonitorMessage); inherited StartTransaction; end; Ich hätte natürlich auch die Methoden "StartTransactionWithMessage" oder so nennen können. Aber wäre das hier sinnvoll/sauber? :gruebel: Ist sicher Ansichtssache. |
AW: Virtuelle Methode überladen
Zitat:
|
AW: Virtuelle Methode überladen
Liste der Anhänge anzeigen (Anzahl: 1)
Nur so nebenbei, weil ich es in deinem Quelltext sehe:
Bei Interfaces und Strings macht es auf jeden Fall Sinn grundsätzlich bei Parametern const zu übergeben, da ansonsten dort jedesmal die Referenzzählung anspringt. Das ist zwar performancemäßig nicht spürbar, wenn solche Methoden nicht sehr oft aufgerufen werden, ist aber dennoch unnötig. Den Unterschied siehst du im Anhang, so klein ist er nicht... |
AW: Virtuelle Methode überladen
Zitat:
Note: Overload finde ich fast immer Blödsinn. Ich würde hier nur eine Methode à la
Delphi-Quellcode:
anbieten. Aber auch das ist Ansichtssache.
Procedure Commit (const aSQLMessage : String = "");
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:24 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 by Thomas Breitkreuz