Question Quelle est la différence entre une fonction abstraite et une fonction virtuelle?


Quelle est la différence entre une fonction abstraite et une fonction virtuelle? Dans quels cas est-il recommandé d'utiliser virtuel ou abstrait? Quelle est l'approche la plus correcte?


1304
2017-12-24 14:11


origine


Réponses:


Une fonction abstraite ne peut pas avoir de fonctionnalité. Vous êtes en train de dire que toute classe enfant DOIT donner sa propre version de cette méthode, mais il est trop général pour essayer même de l'implémenter dans la classe parente.

Une fonction virtuelle, dit en gros, regardez, voici la fonctionnalité qui peut ou ne peut pas être assez bon pour la classe des enfants. Donc, si cela est suffisant, utilisez cette méthode, sinon, remplacez-moi, et fournissez vos propres fonctionnalités.


2325
2017-12-24 14:14



Une fonction abstraite n'a pas d'implémentation et elle ne peut être déclarée que sur une classe abstraite. Cela force la classe dérivée à fournir une implémentation. Une fonction virtuelle fournit une implémentation par défaut et peut exister sur une classe abstraite ou une classe non abstraite. Donc par exemple:

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

244
2017-12-24 14:19



  1. Seulement abstract les classes peuvent avoir abstract membres.
  2. Un non-abstract classe qui hérite d'un abstract classe doit  override ses abstract membres.
  3. Un abstract le membre est implicitement virtual.
  4. Un abstract le membre ne peut pas fournir de mise en œuvre (abstract est appelé pure virtual dans certaines langues).

68
2018-04-16 09:03



Vous devez toujours remplacer une fonction abstraite.

Ainsi:

  • Fonctions abstraites - quand l'héritier doit fournir sa propre implémentation
  • Virtuel - quand il appartient à l'héritier de décider

49
2017-12-24 14:13



Fonction abstraite:

  1. Il ne peut être déclaré qu'à l'intérieur d'une classe abstraite.
  2. Il contient seulement déclaration de méthode pas l'implémentation dans la classe abstraite.
  3. Il doit être remplacé dans la classe dérivée.

Fonction virtuelle

  1. Il peut être déclaré dans une classe abstraite ou non-abstraite.
  2. Il contient l'implémentation de la méthode.
  3. Cela peut être annulé.

30
2018-05-28 07:52



Méthode abstraite Quand une classe contient une méthode abstraite, cette classe doit être déclarée comme abstraite. La méthode abstraite n'a pas d'implémentation et donc, les classes qui dérivent de cette classe abstraite, doivent fournir une implémentation pour cette méthode abstraite.

Méthode virtuelle: Une classe peut avoir une méthode virtuelle. La méthode virtuelle a une implémentation. Lorsque vous héritez d'une classe qui a une méthode virtuelle, vous pouvez substituez la méthode virtuelle et fournissez une logique supplémentaire, ou remplacez la logique par votre propre implémentation.

Quand utiliser quoi: Dans certains cas, vous savez que certains types doivent avoir une méthode spécifique, mais vous ne savez pas quelle implémentation cette méthode devrait avoir.
Dans ce cas, vous pouvez créer une interface contenant une méthode avec cette signature. Cependant, si vous avez un tel cas, mais vous savez que les implémenteurs de cette interface auront également une autre méthode commune (pour laquelle vous pouvez déjà fournir l'implémentation), vous pouvez créer une classe abstraite. Cette classe abstraite contient alors la méthode abstraite (qui doit être surchargée), et une autre méthode qui contient la logique «commune».

Une méthode virtuelle devrait être utilisée si vous avez une classe qui peut être utilisée directement, mais pour laquelle vous voulez que les héritiers puissent changer certains comportements, bien que ce ne soit pas obligatoire.


27
2018-04-16 09:03



explication: avec des analogies. J'espère que cela vous aidera.

Le contexte

Je travaille au 21ème étage d'un immeuble. Et je suis paranoïaque à propos du feu. De temps en temps, quelque part dans le monde, un feu brûle dans un gratte-ciel. Mais heureusement, nous avons un manuel d'instructions quelque part ici sur ce qu'il faut faire en cas d'incendie:

Escalier de secours()

  1. Ne pas recueillir d'effets personnels
  2. Marcher pour échapper à l'incendie
  3. Sortez du bâtiment

Ceci est essentiellement une méthode virtuelle appelée Escalier de secours()

Méthode virtuelle

Ce plan est plutôt bon dans 99% des cas. C'est un plan de base qui fonctionne. Mais il y a 1% de chance que l'issue de secours soit bloquée ou endommagée auquel cas vous êtes complètement foutu et vous deviendrez grillé à moins que vous ne preniez des mesures drastiques. Avec les méthodes virtuelles, vous pouvez faire exactement cela: vous pouvez remplacer le plan de base FireEscape () avec votre propre version du plan:

  1. Courir à la fenêtre
  2. Sauter par la fenêtre
  3. Parachute en toute sécurité vers le bas

En d'autres termes Les méthodes virtuelles fournissent un plan de base qui peut être remplacé si vous devez. Les sous-classes peuvent remplacer la méthode virtuelle de la classe parente si le programmeur le juge approprié.

Méthodes abstraites

Toutes les organisations ne sont pas bien forées. Certaines organisations ne font pas d'exercices d'incendie. Ils n'ont pas de politique globale d'évasion. Chaque homme est pour lui-même. La direction n'est intéressée que par une telle politique existante.

En d'autres termes, chaque personne est forcé développer sa propre méthode FireEscape (). Un gars va sortir de l'escalier de secours. Un autre gars va parachuter. Un autre type utilisera la technologie de propulsion de fusée pour s'envoler du bâtiment. Un autre gars va descendre en rappel. La direction s'en fiche Comment vous échappez, aussi longtemps que vous avez un plan FireEscape () de base - si ce n'est pas le cas, vous pouvez être assuré que la santé et la sécurité au travail descendront sur l'organisation comme une tonne de briques. C'est ce que l'on entend par une méthode abstraite.

Quelle est la différence entre les deux?

Méthode abstraite: les sous-classes sont forcé implémenter leur propre méthode FireEscape. Avec une méthode virtuelle, vous avez un plan de base qui vous attend, mais vous pouvez choisir mettre en œuvre votre propre si ce n'est pas assez bon.

Ce n'était pas si difficile, n'est-ce pas?


23
2018-06-16 01:01



Une méthode abstraite est une méthode qui doit être implémentée pour créer une classe concrète. La déclaration est dans la classe abstraite (et toute classe avec une méthode abstraite doit être une classe abstraite) et doit être implémentée dans une classe concrète.

Une méthode virtuelle est une méthode qui peut être surchargée dans une classe dérivée en utilisant le remplacement, remplacer le comportement dans la superclasse. Si vous ne surchargez pas, vous obtenez le comportement original. Si vous le faites, vous obtenez toujours le nouveau comportement. Cela s'oppose aux méthodes non virtuelles, qui ne peuvent pas être remplacées mais qui peuvent masquer la méthode d'origine. Ceci est fait en utilisant le newmodificateur.

Voir l'exemple suivant:

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

Quand j'instancie DerivedClass et appel SayHello, ou SayGoodbye, Je reçois "Hi There" et "A plus tard". Si j'appelle HelloGoodbye, Je reçois "Bonjour" et "A plus tard". Ceci est dû au fait SayGoodbye est virtuel et peut être remplacé par des classes dérivées. SayHello est seulement caché, donc quand j'appelle cela de ma classe de base, j'obtiens ma méthode originale.

Les méthodes abstraites sont implicitement virtuelles. Ils définissent un comportement qui doit être présent, plus comme une interface.


21
2018-04-16 09:13