web-dev-qa-db-de.com

Was sind virtuelle Methoden?

Warum würden Sie eine Methode als "virtuell" deklarieren? 

Was ist der Vorteil bei der Verwendung von Virtual?

57
mtnclimber10

Der Virtual Modifier wird verwendet, um zu kennzeichnen, dass eine Methode\property (ect) in einer abgeleiteten Klasse mit dem override modifier geändert werden kann.

Beispiel:

class A
{
    public virtual void Foo()
       //DoStuff For A
}

class B : A
{
    public override void Foo()
    //DoStuff For B

    //now call the base to do the stuff for A and B 
    //if required
    base.Foo()
}
44
cgreeno

Virtuell ermöglicht es einer erbenden Klasse, eine Methode zu ersetzen, die die Basisklasse dann verwendet.

public class Thingy
{
    public virtual void StepA()
    {
        Console.Out.WriteLine("Zing");
    }

    public void Action()
    {
        StepA();
        Console.Out.WriteLine("A Thingy in Action.");
    }
}

public class Widget : Thingy
{
    public override void StepA()
    {
        Console.Out.WriteLine("Wiggy");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Thingy thingy = new Thingy();
        Widget widget = new Widget();

        thingy.Action();
        widget.Action();

        Console.Out.WriteLine("Press any key to quit.");
        Console.ReadKey();
    }
 }

Wenn Sie das Programm ausführen, erhalten Sie folgende Ausgabe:

Zing 
A Thingy in Action. 
Wiggy 
A Thingy in Action.

Beachten Sie, dass Widget zwar die auf Thingy-Ebene definierte Action () - Methode aufrief, Thingy intern jedoch die StepA () - Methode von Widget.

Die grundlegende Antwort ist, dass es Erben einer Klasse mehr Flexibilität gibt. Natürlich müssen Sie Ihre Klasse gut konstruieren, sonst könnte es zu Verwüstungen kommen.

39
MrPhil

Eine virtuelle Methode ist ein Methodentyp, bei dem die tatsächlichen Methodenaufrufe vom Laufzeit-Typ des zugrunde liegenden Objekts abhängen. 

Eine nicht virtuelle Methode ist ein Methodentyp, bei dem die tatsächlich aufgerufene Methode vom Referenztyp des Objekts am Punkt des Methodenaufrufs abhängt. 

15
JaredPar

Virtuelle Methoden auf MSDN

Das virtuelle Schlüsselwort wird zum Ändern von .__ verwendet. eine Methoden- oder Eigenschaftsdeklaration in In welchem ​​Fall die Methode oder die Eigenschaft wird als virtuelles Mitglied bezeichnet. Das Implementierung eines virtuellen Members kann von einem übergeordneten Mitglied in .__ geändert werden. eine abgeleitete Klasse.

Wenn eine virtuelle Methode aufgerufen wird, wird die Laufzeittyp des Objekts wird geprüft für ein übergeordnetes Mitglied. Das überschreibendes Mitglied in der am meisten abgeleiteten Klasse wird aufgerufen, die die .__ sein könnte. Originalmitglied, wenn keine abgeleitete Klasse hat das Mitglied überschrieben. (Weitere Informationen über den Laufzeittyp und die meisten abgeleiteten Implementierungen von .__ finden Sie unter 10.5.3 Virtuelle Methoden.)

Standardmäßig sind Methoden nicht virtuell . Sie können eine nicht virtuelle .__ nicht überschreiben. Methode.

Sie können den virtuellen Modifikator nicht verwenden mit folgenden Modifikatoren:

statischabstraktÜberschreiben

Virtuelle Eigenschaften verhalten sich wie abstrakte Methoden, mit Ausnahme der Unterschiede in der Erklärung und Aufrufsyntax.

  • Es ist ein Fehler, den virtuellen Modifikator für eine statische Eigenschaft zu verwenden.
  • Eine virtuelle geerbte Eigenschaft kann in einer abgeleiteten Klasse von .__ überschrieben werden. einschließlich einer Eigenschaftserklärung, die verwendet den Überschreibungsmodifizierer.
11
Russ Cam

Virtuelle Methoden ähneln abstrakten Methoden in Basisklassen, mit der Ausnahme, dass ihre Implementierung für abgeleitete Klassen optional ist. Sie können auch logische Methoden in eine virtuelle Methode einfügen und diese in abgeleiteten Klassen überschreiben.

5
cyclo

Selbst wenn Sie nicht beabsichtigen, von der Klasse abgeleitet zu werden, kann es erforderlich sein, die Methode als virtuell zu kennzeichnen, um die Klasse zu verspotten. Bei einigen Mocking-Frameworks können Sie nur virtuelle Methoden simulieren. Beachten Sie, dass Methoden, die eine Schnittstelle implementieren, implizit virtuell sind.

Ich verwende RhinoMocks, das diese Einschränkung hat, und habe es aus genau diesem Grund als Standard genommen, meine Methoden als virtuell zu kennzeichnen. Für mich ist dies wahrscheinlich der größte Grund, virtuelle Methoden zu verwenden, da Vererbung häufig weniger häufig vorkommt.

5
tvanfosson

Um es bei der Vererbung von Klassen überschreiben zu können. 

Überprüfen Sie den MSDN-Eintrag für das Schlüsselwort. Das erklärt es tiefer.

3
PHeiberg

Eine kurze Frage, eine kurze Antwort!.. Qualifizieren Sie Ihre Methode als "virtuell", wenn Sie glauben, dass Sie die Klasse erben werden, zu der sie gehört.

Eine längere Antwort: "Mit virtual können Sie überschreiben, um Ihrer Methode in einer abgeleiteten Klasse eine andere Bedeutung zu geben.

3
Stephane Halimi

Virtuelle Funktionen sind Funktionen, die nicht wirklich existieren. Die abgeleitete Klasse kann die virtuelle Funktion ändern, indem sie sie überschreibt. Virtuelle Funktionen sind eine Möglichkeit, Laufzeitpolymorphismus zu erzielen

    public class sample {
      public virtual void fun(){
        Console.WriteLine("base sample class \n");
      }
    }
    public class A : sample{
      public override void fun(){
        Console.WriteLine("Class A \n");
      }
    }
    public class B : sample{
      public override void fun(){
        Console.WriteLine("Class B \n");
      }
    }
    class run{
      public static void main(String[] args){
        sample obj = new sample();
        sample obj1 = new A();
        sample obj2 = new B();
        obj.fun();
        obj1.fun();
        obj2.fun();
      }
    }
1
Lineesh K Mohan

Hier wird es mit Beispiel C # Virtual Method klar erklärt.

1
Hitsa

Es ist unnötig zu erwähnen, dass virtuelle Methoden nützlich sind, wenn Ihr Code das Open Closed Principle einhält. 

Lesen Sie mehr über das Open Closed-Prinzip hier , das ursprüngliche OCP-Whitepaper von Uncle Bob.

Bitte beachten Sie auch, dass die Methoden in C # im Gegensatz zu Java standardmäßig nicht virtual sind.

1
abhilash

Die Laufzeit läuft über die Kompilierzeit.
Wenn Sie eine Methode als virtuell deklarieren, müssen Sie in einer abgeleiteten Klasse einen Modifizierer override oder new hinzufügen.
Wir können das sehen, wenn TrySpeak. Passing in Kind und Vater, rufen beide von Vater sprechen an, während TryScream jede Methode aufrufen würde.
Um dies zu verstehen, gibt es einige Dinge, die wir in einer Instanz von Child wissen sollten. Es gibt zwei Scream-Methoden aus der Child-Klasse oder der Father-Klasse. Wir könnten entweder Scream aus der Child-Klasse oder der Father-Klasse aufrufen .__ Da Virtaul Modifier die Methode markiert, kann sie von der abgeleiteten Klasse überschrieben werden, was bedeutet, dass sogar die Scream von der Father-Klasse aufgerufen wird ungünstig, wenn Sie einen neuen Modifikator verwenden. 

import system;
class Father
{
    Speak()
    {
        Console.Writeline("Father is speaking") 
    }
    virtual Scream()
    {
        Console.Writeline("Father is screaming")    
    }
}
class Child: father
{
    Speak()
    {
        Console.Writeline("Child is speaking")  
    }
    override Scream()
    {
        Console.Writeline("Child is screaming") 
    }
}
class APP
{
    public static void Main()
    {
        // We new two instances here
        Father father = new Father();
        Child child = new Child();        
        // Here we call their scream or speak through TryScream or TrySpeak
        TrySpeak(father);
        TrySpeak(child);
        //>>>"Father is speaking"
        //>>>"Father is speaking"
        TryScream(father);
        TryScream(child);
        //>>>"Father is screaming"
        //>>>"Child is screaming"
    }
    // when your method take an Parameter who type is Father
    // You can either pass in a Father instance or
    // A instance of a derived Class from Father
    // which could be Child
    public static void TrySpeak(Father person)
    {
        person.Scream();
    }
    public static void TryScream(Father person)
    {
        person.Speak();
    }
}
1
soulomoon

Dieser Link gibt Ihnen ein einfaches Beispiel https://stackoverflow.com/a/2392656/3373865

1
Anand Kumar Jha

Um die Basisklassenmethode in abgeleiteten Klassen zu überschreiben, müssen Sie die Basisklassenmethode in C # als virtuelle und abgeleitete Klassenmethode als Überschreibung deklarieren, wie unten gezeigt:

using System;
namespace Polymorphism
{
 class A
 {
 public virtual void Test() { Console.WriteLine("A::Test()"); }
 }

 class B : A
 {
 public override void Test() { Console.WriteLine("B::Test()"); }
 }

 class C : B
 {
 public override void Test() { Console.WriteLine("C::Test()"); }
 }

 class Program
 {
 static void Main(string[] args)
 {

 A a = new A();
 B b = new B();
 C c = new C();
 a.Test(); // output --> "A::Test()"
 b.Test(); // output --> "B::Test()"
 c.Test(); // output --> "C::Test()"

 a = new B();
 a.Test(); // output --> "B::Test()"

 b = new C();
 b.Test(); // output --> "C::Test()"

 Console.ReadKey();
 }
 }
}

Sie können das Ausblenden von Methoden und das Überschreiben von Methoden auch mit virtuellen und neuen Schlüsselwörtern kombinieren, da die Methode einer abgeleiteten Klasse gleichzeitig virtuell und neu sein kann. Dies ist erforderlich, wenn Sie die abgeleitete Klassenmethode in der nächsten Ebene weiter überschreiben möchten, während ich die Klasse B, Test () - Methode in Klasse C überschreibe, wie unten gezeigt:

using System;
namespace Polymorphism
{
 class A
 {
 public void Test() { Console.WriteLine("A::Test()"); }
 }

 class B : A
 {
 public new virtual void Test() { Console.WriteLine("B::Test()"); }
 }

 class C : B
 {
 public override void Test() { Console.WriteLine("C::Test()"); }
 }

 class Program
 {
 static void Main(string[] args)
 {

 A a = new A();
 B b = new B();
 C c = new C();

 a.Test(); // output --> "A::Test()"
 b.Test(); // output --> "B::Test()"
 c.Test(); // output --> "C::Test()"

 a = new B();
 a.Test(); // output --> "A::Test()"

 b = new C();
 b.Test(); // output --> "C::Test()"

 Console.ReadKey();
 }
 }
}

GOLDEN WORDS: Das virtuelle Schlüsselwort wird verwendet, um eine in der Basisklasse deklarierte Methode, Eigenschaft, einen Indexer oder ein Ereignis zu ändern und in der abgeleiteten Klasse überschreiben zu lassen.

Das Überschreibungsschlüsselwort wird verwendet, um eine virtuelle/abstrakte Methode, Eigenschaft, einen Indexer oder ein Ereignis der Basisklasse in eine abgeleitete Klasse zu erweitern oder zu ändern.

Das neue Schlüsselwort wird verwendet, um eine Methode, eine Eigenschaft, einen Indexer oder ein Ereignis der Basisklasse in der abgeleiteten Klasse auszublenden.

GENIESSEN :-)

0
Rana Bhopale

der Unterschied zwischen virtuellen und nicht virtuellen Methoden.

Wir haben zwei Klassen. Eine Klasse ist eine Vehicle -Klasse und eine andere ist eine Cart -Klasse. Die Klasse "Fahrzeug" ist die Basisklasse mit zwei Methoden. Eine ist eine virtuelle Methode "Speed ​​()" und eine andere ist eine nicht virtuelle Methode "Average ()". Die virtuelle Basisklassenmethode "Speed ​​()" wird also in der Unterklasse überschrieben. Wir haben eine weitere Klasse "Program" (die Ausführungsklasse), die über einen Einstiegspunkt verfügt, an dem wir eine Instanz der Unterklasse "Cart" erstellen und diese Instanz der Basisklasse "Vehicle" zugewiesen wird. Wenn wir virtuelle und nicht virtuelle Methoden von der Instanz beider Klassen aufrufen, wird die Implementierung der virtuellen Instanzmethode entsprechend dem Laufentyp aufgerufen. Mit anderen Worten, die Instanzen beider Klassen rufen die Subclass-Override-Methode auf, und die aufgerufene nicht-virtuelle Methode wird basierend auf der Instanz der Klasse bestimmt.

using System;

namespace VirtualExample
{   
    class Vehicle
    {   
       public double distance=0.0;
       public double hour =0.0;
       public double fuel =0.0; 

       public Vehicle(double distance, double hour, double fuel)
       {
           this.distance = distance;
           this.hour = hour;
           this.fuel = fuel;
       }

       public void Average()
       {
           double average = 0.0;
           average = distance / fuel;
           Console.WriteLine("Vehicle Average is {0:0.00}", average);
       }

       public virtual void Speed()
       {
           double speed = 0.0;
           speed = distance / hour;
           Console.WriteLine("Vehicle Speed is {0:0.00}", speed);
       }
    } 

    class Car : Vehicle
    {
        public Car(double distance, double hour, double fuel)
            : base(distance, hour, fuel)
        {
        }
      public void Average()
        {
            double average = 0.0;
            average = distance / fuel;
            Console.WriteLine("Car Average is {0:0.00}", average);
        }

        public override void Speed()
        {
            double speed = 0.0;           
            speed = distance / hour;
            Console.WriteLine("Car Speed is {0:0.00}", speed);
        }
    } 

    class Program
   {
        static void Main(string[] args)
        {
             double distance,hour,fuel=0.0;
             Console.WriteLine("Enter the Distance");
             distance = Double.Parse(Console.ReadLine());
             Console.WriteLine("Enter the Hours");
             hour = Double.Parse(Console.ReadLine());
             Console.WriteLine("Enter the Fuel");
             fuel = Double.Parse(Console.ReadLine());
             Car objCar = new Car(distance,hour,fuel);
             Vehicle objVeh = objCar;
             objCar.Average();
             objVeh.Average();
             objCar.Speed();
             objVeh.Speed();
            Console.Read();
        }       
    }
}

 enter image description here

hoffe zu helfen!

0
alvarodoune