Was ist der Unterschied zwischen einer abstrakten Funktion und einer virtuellen Funktion?

1578

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?

Moran Helman
quelle
271
Eine abstrakte Funktion muss überschrieben werden, während eine virtuelle Funktion überschrieben werden kann.
Jordan Parmer
15
Virtuelle Funktionen können eine standardmäßige / generische Implementierung in der Basisklasse haben.
Martin
5
Das Schlüsselwort hier ist abstrakt ; Sie existieren nicht und sind nur eine vage Vorstellung davon, was die Funktion ist (Methodensignatur)
Cole Johnson

Antworten:

2733

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.

BKostenlos
quelle
396
Und wenn Sie eine virtuelle Methode überschreiben, können Sie natürlich immer auf die übergeordnete Methode verweisen, indem Sie base.Foo (...)
Brann
196
Vielen Dank. Dies ist eine viel bessere und einfachere Erklärung als alles in der MSDN-Dokumentation. (Nach fünf Minuten hatte ich Kopfschmerzen: msdn.microsoft.com/en-us/library/aa645767(v=vs.71).aspx )
Jake
15
Als ich aus Java kam, war ich etwas ratlos, warum wir es überhaupt virtuell machen müssen, bis ich dies las: stackoverflow.com/a/1062126/193634
Rosdi Kasim
4
@ MeqDotNet Es bedeutet, wenn Sie meine Implementierung mögen, verwenden Sie mich, wenn Sie nicht Ihre eigenen besser schreiben als ich :)
Usman Younas
16
Dies sollte in der Microsoft-Referenzbibliothek sein, die ich 10 Minuten lang gelesen habe und die immer noch verwirrt ist.
SamChen
303

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:

public abstract class myBase
{
    //If you derive from this class you must implement this method. notice we have no method body here either
    public abstract void YouMustImplement();

    //If you derive from this class you can change the behavior but are not required to
    public virtual void YouCanOverride()
    { 
    }
}

public class MyBase
{
   //This will not compile because you cannot have an abstract method in a non-abstract class
    public abstract void YouMustImplement();
}
JoshBerke
quelle
28
Sehr nützlich, um Beispielcode zu sehen - hilft, die verschiedenen Erklärungen in den Antworten viel klarer zu machen.
Simon Tewsi
2
Ich habe die Antwort auf die vorherige Version zurückgesetzt: Die beiden Klassen sind nur Beispiele, die erste Klasse wird kompiliert, da sie als abstrakt markiert ist, die zweite nicht. Ob MyBase von einer anderen Klasse erbt oder nicht, spielt keine Rolle.
Dirk
2
Muss Ihre MyBaseKlasse die abstrakte Klasse nicht irgendwie implementieren ? Ich mache das nicht oft, also könnte ich mich irren. Das sehe ich in Ihrem Beispiel nicht.
JP2-Code
2
Im obigen Beispiel zeigt MyBase, was Sie nicht können. Das heißt, Sie können keine abstrakte Methode in einer nicht abstrakten Klasse haben
JoshBerke
80
  1. Nur abstractKlassen können abstractMitglieder haben.
  2. Eine Nichtklasse abstract, die von einer abstractKlasse erbt, muss override ihre abstractMitglieder haben.
  3. Ein abstractMitglied ist implizit virtual.
  4. Ein abstractMitglied kann keine Implementierung bereitstellen ( abstractwird pure virtualin einigen Sprachen aufgerufen ).
Mehrdad Afshari
quelle
Nummer 3 macht für mich keinen Sinn. Ich denke, Sie wollten sagen "Ein Mitglied einer abstrakten Klasse ist implizit virtuell" (dh Sie können Funktionen dafür bereitstellen, ohne angeben zu müssen, dass es virtuell ist).
Hobo Spider
5
Nein, ich habe genau das gemeint, was ich geschrieben habe. Ein Mitglied einer abstrakten Klasse kann sein virtualoder nicht virtual. Ein abstractMitglied (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.
Mehrdad Afshari
Das zitierte "Abstrakte Mitglied" ist implizit "virtuell". Aber ich habe irgendwo gesehen, dass jemand abstrakte Mitglieder erstellt hat, indem er explizit das "virtuelle" Schlüsselwort hinzugefügt hat. Was nicht notwendig und tatsächlich ist, gab mir Zweifel, bis ich Ihre Antwort gelesen habe.
BonCodigo
Bitte fügen Sie unterstützende Referenzen für Punkt 4 bei. Und Ihr Beitrag enthält nichts anderes, was die vorherigen noch nicht getan haben.
Rafael
Dies ist lediglich eine Reihe von Aussagen ohne Erklärungen.
Reverse Engineered
61

Sie müssen immer eine abstrakte Funktion überschreiben.

Somit:

  • Abstrakte Funktionen - wenn der Erbe seine eigene Implementierung bereitstellen muss
  • Virtuell - wenn es an dem Erben liegt, zu entscheiden
Rinat Abdullin
quelle
37

Abstrakte Funktion:

  1. Es kann nur innerhalb der abstrakten Klasse deklariert werden.
  2. Es enthält nur die Methodendeklaration, nicht die Implementierung in der abstrakten Klasse.
  3. Es muss in der abgeleiteten Klasse überschrieben werden.

Virtuelle Funktion:

  1. Es kann sowohl in abstrakten als auch in nicht abstrakten Klassen deklariert werden.
  2. Es enthält Methodenimplementierung.
  3. Es kann überschrieben werden.
Lexnim
quelle
29

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.

Frederik Gheysels
quelle
29

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()

  1. Sammle keine Sachen
  2. Gehen Sie zur Feuerleiter
  3. Verlasse das Gebäude

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:

  1. Zum Fenster laufen
  2. Spring aus dem Fenster
  3. Fallschirm sicher nach unten

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?

BKSpurgeon
quelle
22

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 newModifikator.

Siehe folgendes Beispiel:

public class BaseClass
{
    public void SayHello()
    {
        Console.WriteLine("Hello");
    }


    public virtual void SayGoodbye()
    {
        Console.WriteLine("Goodbye");
    }

    public void HelloGoodbye()
    {
        this.SayHello();
        this.SayGoodbye();
    }
}


public class DerivedClass : BaseClass
{
    public new void SayHello()
    {
        Console.WriteLine("Hi There");
    }


    public override void SayGoodbye()
    {
        Console.WriteLine("See you later");
    }
}

Wenn ich instanziiere DerivedClassund anrufe SayHellooder oder SayGoodbye, erhalte ich "Hallo" und "Bis später". Wenn ich anrufe HelloGoodbye, bekomme ich "Hallo" und "Bis später". Dies liegt daran, dass SayGoodbyees virtuell ist und durch abgeleitete Klassen ersetzt werden kann. SayHelloist 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.

Kamiel Wanrooij
quelle
9

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.

Rashack
quelle
9

Ich habe dies vereinfacht, indem ich einige Verbesserungen an den folgenden Klassen vorgenommen habe (aus anderen Antworten):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestOO
{
    class Program
    {
        static void Main(string[] args)
        {
            BaseClass _base = new BaseClass();
            Console.WriteLine("Calling virtual method directly");
            _base.SayHello();
            Console.WriteLine("Calling single method directly");
            _base.SayGoodbye();

            DerivedClass _derived = new DerivedClass();
            Console.WriteLine("Calling new method from derived class");
            _derived.SayHello();
            Console.WriteLine("Calling overrided method from derived class");
            _derived.SayGoodbye();

            DerivedClass2 _derived2 = new DerivedClass2();
            Console.WriteLine("Calling new method from derived2 class");
            _derived2.SayHello();
            Console.WriteLine("Calling overrided method from derived2 class");
            _derived2.SayGoodbye();
            Console.ReadLine();
        }
    }


    public class BaseClass
    {
        public void SayHello()
        {
            Console.WriteLine("Hello\n");
        }
        public virtual void SayGoodbye()
        {
            Console.WriteLine("Goodbye\n");
        }

        public void HelloGoodbye()
        {
            this.SayHello();
            this.SayGoodbye();
        }
    }


    public abstract class AbstractClass
    {
        public void SayHello()
        {
            Console.WriteLine("Hello\n");
        }


        //public virtual void SayGoodbye()
        //{
        //    Console.WriteLine("Goodbye\n");
        //}
        public abstract void SayGoodbye();
    }


    public class DerivedClass : BaseClass
    {
        public new void SayHello()
        {
            Console.WriteLine("Hi There");
        }

        public override void SayGoodbye()
        {
            Console.WriteLine("See you later");
        }
    }

    public class DerivedClass2 : AbstractClass
    {
        public new void SayHello()
        {
            Console.WriteLine("Hi There");
        }
        // We should use the override keyword with abstract types
        //public new void SayGoodbye()
        //{
        //    Console.WriteLine("See you later2");
        //}
        public override void SayGoodbye()
        {
            Console.WriteLine("See you later");
        }
    }
}
MeqDotNet
quelle
6

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:

  • Maschinen sind im Vergleich zu Menschen sehr gut im Suchen und Sortieren
  • Im Vergleich zu Maschinen sind Menschen wirklich gut in Erfindungen und Innovationen

Die kurze Antwort lautet also: virtualist eine späte Bindungsanweisung für die Maschine (Laufzeit), während abstractdie späte Bindungsanweisung für den Menschen (Programmierer) ist.

Mit anderen Worten virtualbedeutet:

"Liebe Laufzeit , binden Sie den entsprechenden Code an diesen Namen, indem Sie das tun, was Sie am besten können: Suchen "

Während abstractbedeutet:

"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 ".

Rodrick Chapman
quelle
3

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).

Brann
quelle
3

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.

  • Wir können den Rückgabetyp der virtuellen Funktion ändern, während wir die
    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.

    public abstract class BaseClass
    { 
        protected abstract void xAbstractMethod();
    
        public virtual void xVirtualMethod()
        {
            var x = 3 + 4;
        }
    } 
    
flik
quelle
2

Ich habe an einigen Stellen gesehen, dass die abstrakte Methode wie folgt definiert ist. ** **.

"Eine abstrakte Methode muss in der untergeordneten Klasse implementiert werden"

** 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.

                                 ----------CODE--------------

public abstract class BaseClass
{
    public int MyProperty { get; set; }
    protected abstract void MyAbstractMethod();

    public virtual void MyVirtualMethod()
    {
        var x = 3 + 4;
    }

}
public abstract class myClassA : BaseClass
{
    public int MyProperty { get; set; }
    //not necessary to implement an abstract method if the child class is also abstract.

    protected override void MyAbstractMethod()
    {
        throw new NotImplementedException();
    }
}
public class myClassB : BaseClass
{
    public int MyProperty { get; set; }
    //You must have to implement the abstract method since this class is not an abstract class.

    protected override void MyAbstractMethod()
    {
        throw new NotImplementedException();
    }
}
Kod
quelle
2

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:

  1. Finde den Feind
  2. Neutralisiere ihn.
  3. Trinken Sie danach ein Bier

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:

  1. Finde den Feind.
  2. Schieß ihm in den Kopf.
  3. Nach Hause gehen
  4. Bier trinken.

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:

  1. Finde den Feind.
  2. Lassen Sie ihn mit einigen BS-Anklagen verhaften.
  3. Nach Hause gehen
  4. Bier trinken.

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.

BKSpurgeon
quelle
2

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.

Kedarnath MS
quelle
1

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.

Komm herein
quelle
1

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

Yeasin Abedin Siam
quelle
1

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

Mohammad Nikravesh
quelle
1

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.

Sagi Berco
quelle
1

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.

x-rw
quelle
0

In C # gibt es keine Aufrufe für virtuelle Klassen.

Für Funktionen

  1. Abstrakte Funktionen haben nur Signatur, die Laufwerksklasse sollte mit Funktionalität überschrieben werden.
  2. Die virtuelle Funktion enthält den Teil der Funktionalität, den die Laufwerksklasse je nach Anforderung überschreiben kann oder nicht

Sie können mit Ihrer Anforderung entscheiden.

Nithila Shanmugananthan
quelle
0

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.

Vinay Chanumolu
quelle
0

Aus einem C ++ - Hintergrund entspricht C # virtual C ++ virtual, während C # abstrakte Methoden der rein virtuellen C ++ - Funktion entsprechen

Yituo
quelle
0

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.

Ciro Corvino
quelle
0

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

public interface ExampleInterface {

//    public void MethodBodyInInterfaceNotPossible(){
//    }
    void MethodInInterface();

}

public abstract class AbstractClass {
    public abstract void AbstractMethod();

    //    public abstract void AbstractMethodWithBodyNotPossible(){
    //
    //    };

    //Standard Method CAN be declared in AbstractClass
    public void StandardMethod(){
        System.out.println("Standard Method in AbstractClass (super) runs");
    }
}

public class ConcreteClass
    extends AbstractClass
    implements ExampleInterface{

    //Abstract Method HAS TO be IMPLEMENTED in child class. Implemented by ConcreteClass
    @Override
    public void AbstractMethod() {
        System.out.println("AbstractMethod overridden runs");
    }

    //Standard Method CAN be OVERRIDDEN.
    @Override
    public void StandardMethod() {
        super.StandardMethod();
        System.out.println("StandardMethod overridden in ConcreteClass runs");
    }

    public void ConcreteMethod(){
        System.out.println("Concrete method runs");
    }

    //A method in interface HAS TO be IMPLEMENTED in implementer class.
    @Override
    public void MethodInInterface() {
        System.out.println("MethodInInterface Implemented by ConcreteClass runs");

    //    Cannot declare abstract method in a concrete class
    //    public abstract void AbstractMethodDeclarationInConcreteClassNotPossible(){
    //
    //    }
    }
}
U.Savas
quelle
-4

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.

Qaiser
quelle