web-dev-qa-db-fra.com

Quelles sont les méthodes virtuelles?

Pourquoi déclareriez-vous une méthode comme "virtuelle"? 

Quel est l'avantage d'utiliser le virtuel?

57
mtnclimber10

Le modificateur Virtual permet d'indiquer qu'une méthode\property (ect) peut être modifiée dans une classe dérivée à l'aide du modificateur override .

Exemple:

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

Virtual permet à une classe héréditaire de remplacer une méthode que la classe de base utilise ensuite.

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

Lorsque vous exécutez le programme, votre sortie sera:

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

Remarquez que même si Widget appelait la méthode Action () définie au niveau Thingy, Thingy l'appelait en interne la méthode StepA () de Widget.

La réponse de base est que cela donne plus de flexibilité aux héritiers d’une classe. Bien sûr, vous devez bien organiser votre classe, sinon cela pourrait faire des ravages.

39
MrPhil

Une méthode virtuelle est un type de méthode où les appels de méthode réels dépendent du type d'exécution de l'objet sous-jacent. 

Une méthode non virtuelle est un type de méthode où la méthode réelle appelée dépend du type de référence de l'objet au moment de l'appel de la méthode. 

15
JaredPar

Méthodes virtuelles sur MSDN

Le mot-clé virtual est utilisé pour modifier une déclaration de méthode ou de propriété, en auquel cas la méthode ou la propriété s'appelle un membre virtuel. Le la mise en œuvre d'un membre virtuel peut être modifié par un membre dominant dans une classe dérivée.

Lorsqu'une méthode virtuelle est invoquée, le fichier le type d'exécution de l'objet est vérifié pour un membre dominant. Le membre prépondérant dans le plus dérivé la classe est appelée, ce qui pourrait être le membre d'origine, s'il n'y a pas de classe dérivée a remplacé le membre. (Pour plus d'informations sur le type d'exécution et la plupart des implémentations dérivées de , Voir 10.5.3 Méthodes virtuelles.)

Par défaut, les méthodes ne sont pas virtuelles . Vous ne pouvez pas remplacer un .__ non virtuel. méthode.

Vous ne pouvez pas utiliser le modificateur virtuel avec les modificateurs suivants:

statique _ {résumésubstitution

Les propriétés virtuelles se comportent comme méthodes abstraites, sauf pour le différences dans les déclarations et syntaxe d'invocation.

  • C'est une erreur d'utiliser le modificateur virtuel sur une propriété statique.
  • Une propriété héritée virtuelle peut être remplacée dans une classe dérivée par y compris une déclaration de propriété que utilise le modificateur de substitution.
11
Russ Cam

Les méthodes virtuelles sont similaires aux méthodes abstraites dans les classes de base, sauf que leur implémentation sur des classes dérivées est facultative. Vous pouvez aussi mettre la logique dans la méthode virtuelle et la remplacer dans les classes dérivées.

5
cyclo

Même si vous n'envisagez pas de dériver de la classe, il peut être nécessaire de marquer la méthode de façon virtuelle afin de vous moquer de la classe. Certains frameworks moqueurs vous permettent uniquement de vous moquer de méthodes virtuelles. Notez que les méthodes implémentant une interface sont implicitement virtuelles.

J'utilise RhinoMocks qui a cette restriction et commence à marquer mes méthodes virtuelles par défaut pour cette raison uniquement. Pour moi, c'est probablement la principale raison d'utiliser des méthodes virtuelles car les cas où l'héritage entre en jeu sont beaucoup moins fréquents.

5
tvanfosson

Afin de pouvoir le remplacer dans les classes héritées. 

Consultez l'entrée MSDN pour le mot clé. Cela l'explique plus en profondeur.

3
PHeiberg

Une question brève, une réponse brève! Qualifiez votre méthode de "virtuelle" si vous pensez hériter de la classe à laquelle elle appartient.

Une réponse plus longue: "virtual vous permet de remplacer, de donner un autre sens à votre méthode dans une classe dérivée.

3
Stephane Halimi

Les fonctions virtuelles sont les fonctions qui n'existent pas vraiment. La classe dérivée peut modifier la fonction virtuelle en la remplaçant. Les fonctions virtuelles sont l’un des moyens de réaliser un polymorphisme à l’exécution

    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

Ici, il est expliqué clairement avec exemple Méthode virtuelle C #

1
Hitsa

Inutile de dire que les méthodes virtuelles sont pratiques lorsque votre code essaie de respecter le principe Open Closed Principle

En savoir plus sur le principe ouvert/fermé ici , le livre blanc OCP original de Oncle Bob.

Sachez également que les méthodes sont not virtuelles par défaut en C # contrairement à Java.

1
abhilash

Le runtime se déroule sur le temps de compilation.
Lorsque vous déclarez une méthode comme virtuelle, pour la déclarer dans une classe dérivée, vous devez ajouter un modificateur override ou new.
nous pouvons voir que quand TrySpeak. Passer l'enfant et le père, les deux appellent Parler du père, alors que TryScream, appellerait chaque méthode.
Pour comprendre cela, nous devons savoir certaines choses, dans un exemple de Child, il existe deux méthodes Scream de la classe Child ou de la classe Père. Nous pourrions appeler la variable Scream depuis la classe Child ou la classe Père . Parce que Virtaul Modificateur marque la méthode de sorte qu'elle puisse être annulée par la classe dérivée, ce qui signifie que même la Scream est appelée depuis la classe Père, elle est annulée, ce serait defferent si vous utilisez un nouveau modificateur. 

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

Ce lien vous fournira une meilleure compréhension avec un exemple très simple https://stackoverflow.com/a/2392656/3373865

1
Anand Kumar Jha

En C #, pour substituer la méthode de classe de base dans une classe dérivée, vous devez déclarer la méthode de classe de base en tant que méthode de classe virtuelle et dérivée en tant que substitution, comme indiqué ci-dessous:

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

Vous pouvez également combiner le masquage de méthode et le remplacement de méthode en utilisant les mots-clés virtual et new, car la méthode d'une classe dérivée peut être à la fois virtuelle et nouvelle. Cela est nécessaire si vous souhaitez redéfinir la méthode de la classe dérivée au niveau suivant, car je substitue la méthode Test B de la classe B à la classe C, comme indiqué ci-dessous:

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: Le mot clé virtual est utilisé pour modifier une méthode, une propriété, un indexeur ou un événement déclaré dans la classe de base et permettre son remplacement dans la classe dérivée.

Le mot-clé override est utilisé pour étendre ou modifier une méthode, une propriété, un indexeur ou un événement virtuel/abstrait de la classe de base en classe dérivée.

Le nouveau mot-clé est utilisé pour masquer une méthode, une propriété, un indexeur ou un événement de la classe de base en classe dérivée.

PRENDRE PLAISIR :-)

0
Rana Bhopale

la différence entre les méthodes virtuelles et non virtuelles.

Nous avons deux classes; l'un est une classe Vehicle et un autre est une classe Cart. La classe "Vehicle" est la classe de base qui a deux méthodes; l'une est une méthode virtuelle "Speed ​​()" et l'autre est une méthode non virtuelle "Moyenne ()". Ainsi, la méthode virtuelle de classe de base "Speed ​​()" est remplacée par la sous-classe. Nous avons encore une classe "Programme" (la classe d'exécution) qui a un point d'entrée où nous créons une instance de la sous-classe "Cart" et cette instance est affectée au type de base "Véhicule" Lorsque nous appelons des méthodes virtuelles et non virtuelles par l'instance des deux classes, le type d'exécution de la méthode virtuelle est invoqué en fonction du type d'exécution. en d'autres termes, les deux instances de la classe invoquent la méthode de substitution de sous-classe et la méthode non virtuelle invoquée est déterminée en fonction de l'instance de la classe.

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

espérons pouvoir aider!

0
alvarodoune