Was ist der Unterschied zwischen einer abstrakten Funktion und einer virtuellen Funktion? In welchen Fällen wird die Verwendung von virtuell oder abstrakt empfohlen? Welcher ist der beste Ansatz?
oop
programming-languages
abstract
virtual-functions
Moran Helman
quelle
quelle
Antworten:
Eine abstrakte Funktion kann keine Funktionalität haben. Sie sagen im Grunde, jede untergeordnete Klasse MUSS ihre eigene Version dieser Methode angeben, es ist jedoch zu allgemein, um überhaupt zu versuchen, sie in der übergeordneten Klasse zu implementieren.
Eine virtuelle Funktion bedeutet im Grunde genommen "Schauen". Hier ist die Funktionalität, die für die untergeordnete Klasse möglicherweise gut genug ist oder nicht. Wenn es also gut genug ist, verwenden Sie diese Methode, wenn nicht, überschreiben Sie mich und stellen Sie Ihre eigenen Funktionen bereit.
quelle
Eine abstrakte Funktion hat keine Implementierung und kann nur für eine abstrakte Klasse deklariert werden. Dies zwingt die abgeleitete Klasse, eine Implementierung bereitzustellen.
Eine virtuelle Funktion stellt eine Standardimplementierung bereit und kann entweder in einer abstrakten Klasse oder in einer nicht abstrakten Klasse vorhanden sein.
Also zum Beispiel:
quelle
MyBase
Klasse die abstrakte Klasse nicht irgendwie implementieren ? Ich mache das nicht oft, also könnte ich mich irren. Das sehe ich in Ihrem Beispiel nicht.abstract
Klassen könnenabstract
Mitglieder haben.abstract
, die von einerabstract
Klasse erbt, mussoverride
ihreabstract
Mitglieder haben.abstract
Mitglied ist implizitvirtual
.abstract
Mitglied kann keine Implementierung bereitstellen (abstract
wirdpure virtual
in einigen Sprachen aufgerufen ).quelle
virtual
oder nichtvirtual
. Einabstract
Mitglied (dh abstrakte Eigenschaft, abstrakte Methode) ist wie eine virtuelle Methode, dh Sie können es überschreiben, außer dass es keine Standardimplementierung mit sich führt.Sie müssen immer eine abstrakte Funktion überschreiben.
Somit:
quelle
Abstrakte Funktion:
Virtuelle Funktion:
quelle
Abstrakte Methode: Wenn eine Klasse eine abstrakte Methode enthält, muss diese Klasse als abstrakt deklariert werden. Die abstrakte Methode hat keine Implementierung und daher müssen Klassen, die von dieser abstrakten Klasse abgeleitet sind, eine Implementierung für diese abstrakte Methode bereitstellen.
Virtuelle Methode: Eine Klasse kann eine virtuelle Methode haben. Die virtuelle Methode hat eine Implementierung. Wenn Sie von einer Klasse erben , die eine virtuelle Methode ist, Sie können die virtuelle Methode überschreiben und eine zusätzliche Logik zur Verfügung stellen, oder die Logik mit Ihrer eigenen Implementierung ersetzen.
Wann was zu verwenden ist: In einigen Fällen wissen Sie, dass bestimmte Typen eine bestimmte Methode haben sollten, aber Sie wissen nicht, welche Implementierung diese Methode haben sollte.
In solchen Fällen können Sie eine Schnittstelle erstellen, die eine Methode mit dieser Signatur enthält. Wenn Sie jedoch einen solchen Fall haben, aber wissen, dass Implementierer dieser Schnittstelle auch über eine andere allgemeine Methode verfügen (für die Sie die Implementierung bereits bereitstellen können), können Sie eine abstrakte Klasse erstellen. Diese abstrakte Klasse enthält dann die abstrakte Methode (die überschrieben werden muss) und eine andere Methode, die die 'gemeinsame' Logik enthält.
Eine virtuelle Methode sollte verwendet werden, wenn Sie über eine Klasse verfügen, die direkt verwendet werden kann, für die jedoch Erben bestimmte Verhaltensweisen ändern sollen, obwohl dies nicht obligatorisch ist.
quelle
Erklärung: mit Analogien. hoffentlich hilft es dir.
Kontext
Ich arbeite im 21. Stock eines Gebäudes. Und ich bin paranoid in Bezug auf Feuer. Hin und wieder brennt irgendwo auf der Welt ein Feuer einen Wolkenkratzer nieder. Aber zum Glück haben wir hier irgendwo eine Bedienungsanleitung, was im Brandfall zu tun ist:
Notausgang()
Dies ist im Grunde eine virtuelle Methode namens FireEscape ()
Virtuelle Methode
Dieser Plan ist für 99% der Umstände ziemlich gut. Es ist ein grundlegender Plan, der funktioniert. Es besteht jedoch eine Wahrscheinlichkeit von 1%, dass die Feuerleiter blockiert oder beschädigt wird. In diesem Fall sind Sie vollständig verschraubt und werden zum Toast, es sei denn, Sie ergreifen drastische Maßnahmen. Mit virtuellen Methoden können Sie genau das tun: Sie können den grundlegenden FireEscape () - Plan mit Ihrer eigenen Version des Plans überschreiben:
Mit anderen Worten, virtuelle Methoden bieten einen Basisplan, der bei Bedarf überschrieben werden kann . Unterklassen können die virtuelle Methode der übergeordneten Klasse überschreiben, wenn der Programmierer dies für angemessen hält.
Abstrakte Methoden
Nicht alle Organisationen sind gut ausgebildet. Einige Organisationen führen keine Feuerwehrübungen durch. Sie haben keine allgemeine Fluchtpolitik. Jeder Mann ist für sich. Das Management ist nur an einer solchen bestehenden Politik interessiert.
Mit anderen Worten, jede Person ist gezwungen , ihre eigene FireEscape () -Methode zu entwickeln. Ein Mann wird die Feuerleiter verlassen. Ein anderer Typ wird Fallschirm springen. Ein anderer Mann wird Raketenantriebstechnologie verwenden, um vom Gebäude wegzufliegen. Ein anderer Typ wird sich abseilen. Dem Management ist es egal, wie Sie entkommen, solange Sie einen grundlegenden FireEscape () -Plan haben. Wenn dies nicht der Fall ist, können Sie sicher sein, dass der Arbeitsschutz wie eine Tonne Steine auf das Unternehmen fällt. Dies ist mit einer abstrakten Methode gemeint.
Was ist der Unterschied zwischen den beiden wieder?
Abstrakte Methode: Unterklassen sind gezwungen , ihre eigene Methode Fireescape zu implementieren. Bei einer virtuellen Methode wartet ein grundlegender Plan auf Sie, Sie können jedoch auch einen eigenen implementieren, wenn dieser nicht gut genug ist.
Das war doch nicht so schwer, oder?
quelle
Eine abstrakte Methode ist eine Methode, die implementiert werden muss, um eine konkrete Klasse zu erstellen. Die Deklaration befindet sich in der abstrakten Klasse (und jede Klasse mit einer abstrakten Methode muss eine abstrakte Klasse sein) und muss in einer konkreten Klasse implementiert sein.
Eine virtuelle Methode ist eine Methode, die in einer abgeleiteten Klasse mithilfe der Überschreibung überschrieben werden kann und das Verhalten in der Oberklasse ersetzt. Wenn Sie nicht überschreiben, erhalten Sie das ursprüngliche Verhalten. Wenn Sie dies tun, erhalten Sie immer das neue Verhalten. Dies steht im Gegensatz zu nicht virtuellen Methoden, die nicht überschrieben werden können, sondern die ursprüngliche Methode verbergen können. Dies erfolgt mit dem
new
Modifikator.Siehe folgendes Beispiel:
Wenn ich instanziiere
DerivedClass
und anrufeSayHello
oder oderSayGoodbye
, erhalte ich "Hallo" und "Bis später". Wenn ich anrufeHelloGoodbye
, bekomme ich "Hallo" und "Bis später". Dies liegt daran, dassSayGoodbye
es virtuell ist und durch abgeleitete Klassen ersetzt werden kann.SayHello
ist nur versteckt, also wenn ich das von meiner Basisklasse aufrufe, bekomme ich meine ursprüngliche Methode.Abstrakte Methoden sind implizit virtuell. Sie definieren Verhalten, das vorhanden sein muss, eher wie eine Schnittstelle.
quelle
Abstrakte Methoden sind immer virtuell. Sie können keine Implementierung haben.
Das ist der Hauptunterschied.
Grundsätzlich würden Sie eine virtuelle Methode verwenden, wenn Sie die Standardimplementierung haben und Nachkommen erlauben möchten, ihr Verhalten zu ändern.
Mit einer abstrakten Methode zwingen Sie Nachkommen, eine Implementierung bereitzustellen.
quelle
Ich habe dies vereinfacht, indem ich einige Verbesserungen an den folgenden Klassen vorgenommen habe (aus anderen Antworten):
quelle
Beim Binden wird ein Name einer Codeeinheit zugeordnet.
Späte Bindung bedeutet, dass wir den Namen verwenden, aber die Zuordnung verschieben. Mit anderen Worten, wir erstellen / erwähnen zuerst den Namen und lassen einen nachfolgenden Prozess die Zuordnung von Code zu diesem Namen durchführen.
Betrachten Sie nun:
Die kurze Antwort lautet also:
virtual
ist eine späte Bindungsanweisung für die Maschine (Laufzeit), währendabstract
die späte Bindungsanweisung für den Menschen (Programmierer) ist.Mit anderen Worten
virtual
bedeutet:"Liebe Laufzeit , binden Sie den entsprechenden Code an diesen Namen, indem Sie das tun, was Sie am besten können: Suchen "
Während
abstract
bedeutet:"Lieber Programmierer , bitte binden Sie den entsprechenden Code an diesen Namen, indem Sie das tun, was Sie am besten können: Erfinden "
Der Vollständigkeit halber bedeutet Überladung :
"Lieber Compiler , binden Sie den entsprechenden Code an diesen Namen, indem Sie das tun, was Sie am besten können: Sortieren ".
quelle
Grundsätzlich verwenden Sie eine virtuelle Methode, wenn die Erben die Funktionalität erweitern sollen, wenn sie dies möchten.
Sie verwenden abstrakte Methoden, wenn die Erben die Funktionalität implementieren sollen (und in diesem Fall haben sie keine Wahl).
quelle
Virtuelle Methode :
Virtuell bedeutet, dass wir es überschreiben können.
Die virtuelle Funktion hat eine Implementierung. Wenn wir die Klasse erben, können wir die virtuelle Funktion überschreiben und unsere eigene Logik bereitstellen.
Funktion in der untergeordneten Klasse implementieren (was als Konzept von
Shadowing bezeichnet werden kann).
Abstrakte Methode
Abstrakt bedeutet, dass wir es überschreiben müssen.
Eine abstrakte Funktion hat keine Implementierung und muss sich in einer abstrakten Klasse befinden.
Es kann nur deklariert werden. Dies zwingt die abgeleitete Klasse, die Implementierung bereitzustellen.
Ein abstraktes Mitglied ist implizit virtuell. Das Abstract kann in einigen Sprachen als rein virtuell bezeichnet werden.
quelle
Ich habe an einigen Stellen gesehen, dass die abstrakte Methode wie folgt definiert ist. ** **.
** Ich hatte das Gefühl, dass es so ist.
Es ist nicht erforderlich, dass eine abstrakte Methode in einer untergeordneten Klasse implementiert werden muss, wenn die untergeordnete Klasse ebenfalls abstrakt ist .
1) Eine abstrakte Methode kann nicht eine private Methode. 2) Eine abstrakte Methode kann nicht in derselben abstrakten Klasse implementiert werden.
Ich würde sagen ... wenn wir eine abstrakte Klasse implementieren, müssen Sie die abstrakten Methoden aus der abstrakten Basisklasse überschreiben. Weil .. Die Implementierung der abstrakten Methode erfolgt mit dem Schlüsselwort override. Ähnlich der virtuellen Methode.
Es ist nicht erforderlich, dass eine virtuelle Methode in einer geerbten Klasse implementiert wird.
quelle
Die meisten der oben genannten Beispiele verwenden Code - und sie sind sehr, sehr gut. Ich muss nicht zu dem hinzufügen, was sie sagen, aber das Folgende ist eine einfache Erklärung, die Analogien anstelle von Code / technischen Begriffen verwendet.
Einfache Erklärung - Erklärung unter Verwendung von Analogien
Abstrakte Methode
Denken Sie an George W. Bush. Er sagt zu seinen Soldaten: "Kämpfe im Irak". Und das ist es. Alles, was er angegeben hat, ist, dass gekämpft werden muss. Er gibt nicht an, wie genau das passieren wird. Aber ich meine, du kannst nicht einfach rausgehen und "kämpfen": Was bedeutet das genau? kämpfe ich mit einer B-52 oder meinem Derringer? Diese spezifischen Details werden jemand anderem überlassen. Dies ist eine abstrakte Methode.
Virtuelle Methode
David Petraeus ist hoch oben in der Armee. Er hat definiert, was Kampf bedeutet:
Das Problem ist, dass es sich um eine sehr allgemeine Methode handelt. Es ist eine gute Methode, die funktioniert, aber manchmal nicht spezifisch genug ist. Das Gute für Petraeus ist, dass seine Befehle Spielraum und Umfang haben - er hat anderen erlaubt, seine Definition von "Kampf" entsprechend ihren besonderen Anforderungen zu ändern.
Private Job Bloggs liest Petraeus 'Befehl und erhält die Erlaubnis, seine eigene Version des Kampfes gemäß seinen besonderen Anforderungen zu implementieren:
Nouri al Maliki erhält die gleichen Befehle auch von Petraeus. Er soll auch kämpfen. Aber er ist ein Politiker, kein Infanterist. Offensichtlich kann er nicht herumlaufen und seinen politischen Feinden in den Kopf schießen. Da Petraeus ihm eine virtuelle Methode gegeben hat, kann Maliki seine eigene Version der Kampfmethode entsprechend seinen besonderen Umständen implementieren:
Mit anderen Worten, eine virtuelle Methode bietet Anweisungen auf der Kesselplatte - dies sind jedoch allgemeine Anweisungen, die von Personen in der gesamten Heerie der Armee je nach ihren besonderen Umständen präzisiert werden können.
Der Unterschied zwischen den beiden
George Bush beweist keine Implementierungsdetails. Dies muss von jemand anderem bereitgestellt werden. Dies ist eine abstrakte Methode.
Petraeus auf der anderen Seite tut Details Implementierung zur Verfügung stellen , aber er hat für seine Untergebenen die Erlaubnis gegeben , seine Befehle mit ihrer eigenen Version außer Kraft zu setzen, wenn sie besser etwas einfallen kann.
Ich hoffe, das hilft.
quelle
Abstrakte Funktion (Methode):
● Eine abstrakte Methode ist eine Methode, die mit dem Schlüsselwort abstract deklariert wird.
● Es hat keinen Körper.
● Es sollte von der abgeleiteten Klasse implementiert werden.
● Wenn eine Methode abstrakt ist, sollte die Klasse abstrakt sein.
virtuelle Funktion (Methode):
● Eine virtuelle Methode ist die Methode, die mit dem Schlüsselwort virtual deklariert ist und von der abgeleiteten Klassenmethode mithilfe des Schlüsselworts override überschrieben werden kann.
● Es liegt an der abgeleiteten Klasse, ob sie überschrieben wird oder nicht.
quelle
Die Antwort wurde mehrmals gegeben, aber die Frage, wann sie verwendet werden soll, ist eine Entscheidung zur Entwurfszeit. Ich würde es als gute Praxis ansehen, zu versuchen, gemeinsame Methodendefinitionen in unterschiedlichen Schnittstellen zu bündeln und sie in Klassen auf geeigneten Abstraktionsebenen zu ziehen. Durch das Speichern einer gemeinsamen Gruppe abstrakter und virtueller Methodendefinitionen in einer Klasse wird die Klasse nicht mehr zu verantworten, wenn es am besten ist, eine nicht abstrakte Klasse zu definieren, die eine Reihe präziser Schnittstellen implementiert. Wie immer hängt es davon ab, was Ihren anwendungsspezifischen Anforderungen am besten entspricht.
quelle
Die abstrakte Funktion kann keinen Körper haben und MUSS von untergeordneten Klassen überschrieben werden
Die virtuelle Funktion hat einen Körper und kann von untergeordneten Klassen überschrieben werden oder nicht
quelle
Aus allgemeiner objektorientierter Sicht:
Bezüglich der abstrakten Methode : Wenn Sie eine abstrakte Methode in die übergeordnete Klasse einfügen, sagen Sie tatsächlich zu den untergeordneten Klassen: Hey, beachten Sie, dass Sie eine Methodensignatur wie diese haben. Und wenn Sie es verwenden möchten, sollten Sie Ihr eigenes implementieren!
In Bezug auf die virtuelle Funktion : Wenn Sie eine virtuelle Methode in die übergeordnete Klasse einfügen, sagen Sie zu den abgeleiteten Klassen: Hey, hier gibt es eine Funktionalität, die etwas für Sie tut. Wenn dies für Sie nützlich ist, verwenden Sie es einfach. Wenn nicht, überschreiben Sie dies und implementieren Sie Ihren Code, auch Sie können meine Implementierung in Ihrem Code verwenden!
Dies ist eine Philosophie über den Unterschied zwischen diesen beiden Konzepten in General OO
quelle
Eine abstrakte Funktion ist "nur" eine Signatur ohne Implementierung. Es wird in einer Schnittstelle verwendet, um zu deklarieren, wie die Klasse verwendet werden kann. Es muss in einer der abgeleiteten Klassen implementiert werden.
Die virtuelle Funktion (Methode tatsächlich) ist eine Funktion, die Sie ebenfalls deklarieren und die in einer der Vererbungshierarchieklassen implementiert werden sollte.
Die geerbten Instanzen einer solchen Klasse erben auch die Implementierung, sofern Sie sie nicht implementieren, in einer Klasse mit niedrigerer Hierarchie.
quelle
Wenn eine Klasse von dieser abstrakten Klasse abgeleitet ist, muss sie das abstrakte Element überschreiben. Dies unterscheidet sich vom virtuellen Modifikator, der angibt, dass das Mitglied optional überschrieben werden kann.
quelle
In C # gibt es keine Aufrufe für virtuelle Klassen.
Für Funktionen
Sie können mit Ihrer Anforderung entscheiden.
quelle
Die abstrakte Methode hat keine Implementierung. Sie wird in der übergeordneten Klasse deklariert. Die untergeordnete Klasse ist für die Implementierung dieser Methode verantwortlich.
Die virtuelle Methode sollte eine Implementierung in der übergeordneten Klasse haben und erleichtert der untergeordneten Klasse die Auswahl, ob diese Implementierung der übergeordneten Klasse verwendet werden soll oder ob für diese Methode in der untergeordneten Klasse eine neue Implementierung für sich selbst erstellt werden soll.
quelle
Aus einem C ++ - Hintergrund entspricht C # virtual C ++ virtual, während C # abstrakte Methoden der rein virtuellen C ++ - Funktion entsprechen
quelle
Eine abstrakte Funktion oder Methode ist ein öffentlicher "Operationsname", der von einer Klasse verfügbar gemacht wird. Ihr Ziel ist es, zusammen mit abstrakten Klassen in erster Linie eine Form der Einschränkung beim Objektdesign gegenüber der Struktur bereitzustellen, die ein Objekt implementieren muss.
Tatsächlich müssen die Klassen, die von ihrer abstrakten Klasse erben, eine Implementierung für diese Methode geben. Im Allgemeinen verursachen Compiler Fehler, wenn sie dies nicht tun.
Die Verwendung abstrakter Klassen und Methoden ist vor allem wichtig, um zu vermeiden, dass die Klassenstruktur durch die Konzentration auf Implementierungsdetails beim Entwerfen von Klassen zu stark mit den Implementierungen verknüpft wird, sodass Abhängigkeiten und Kopplungen zwischen Klassen entstehen, die zwischen ihnen zusammenarbeiten.
Eine virtuelle Funktion oder Methode ist einfach eine Methode, die ein öffentliches Verhalten einer Klasse modelliert, die wir jedoch in der Vererbungskette ändern können, da wir der Ansicht sind, dass untergeordnete Klassen möglicherweise bestimmte Erweiterungen für dieses Verhalten implementieren müssen.
Beide repräsentieren eine Form des Polymorpfhismus im Objektorientierungsparadigma.
Wir können abstrakte Methoden und virtuelle Funktionen zusammen verwenden, um ein gutes Vererbungsmodell zu unterstützen.
Wir entwerfen eine gute abstrakte Struktur der Hauptobjekte unserer Lösung, erstellen dann grundlegende Implementierungen, indem wir diejenigen lokalisieren, die für weitere Spezialisierungen anfälliger sind, und machen diese als virtuelle Objekte. Schließlich spezialisieren wir unsere grundlegenden Implementierungen und überschreiben schließlich geerbte virtuelle.
quelle
Hier schreibe ich einen Beispielcode in der Hoffnung, dass dies ein ziemlich greifbares Beispiel ist, um das Verhalten der Schnittstellen, abstrakten Klassen und gewöhnlichen Klassen auf einer sehr grundlegenden Ebene zu sehen. Sie können diesen Code auch in github als Projekt finden, wenn Sie ihn als Demo verwenden möchten: https://github.com/usavas/JavaAbstractAndInterfaceDemo
quelle
Zu meinem Verständnis:
Abstrakte Methoden:
Nur die abstrakte Klasse kann abstrakte Methoden enthalten. Auch die abgeleitete Klasse muss die Methode implementieren und es wird keine Implementierung in der Klasse bereitgestellt.
Virtuelle Methoden:
Eine Klasse kann diese deklarieren und auch deren Implementierung bereitstellen. Auch die abgeleitete Klasse muss die Methode implementieren, um sie zu überschreiben.
quelle