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 la meilleure approche?

1341
demandé sur iBug 2008-12-24 17:11:43

23 réponses

une fonction abstraite ne peut pas avoir de fonctionnalité. vous êtes essentiellement en train de dire, toute classe d'enfant doit donner leur propre version de cette méthode, mais il est trop général pour même essayer de mettre en œuvre dans la classe de parent.

une fonction virtuelle , est essentiellement dire regardez, voici la fonctionnalité qui peut ou ne peut pas être assez bon pour la classe de l'enfant. Donc, si c'est suffisant, utilisez cette méthode, sinon, passez-la-moi, et offrez vos propres fonctionnalités.

2368
répondu BFree 2016-03-15 15:47:03

une fonction abstraite n'a pas de mise en œuvre et 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 il peut exister sur une classe abstraite ou une non-classe abstraite. Ainsi 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();
}
254
répondu JoshBerke 2014-06-12 08:14:39
  1. seulement abstract les classes peuvent avoir des membres abstract .
  2. une classe non - abstract qui hérite d'une abstract classe doit override ses abstract membres.
  3. Un abstract membre est implicitement virtual .
  4. Un abstract membre ne peut pas fournir toute mise en œuvre ( abstract est appelé pure virtual dans certaines langues).
71
répondu Mehrdad Afshari 2009-04-16 09:03:40

vous devez toujours surcharger une fonction abstraite.

ainsi:

  • fonctions abstraites - quand l'héritier doit fournir sa propre mise en œuvre
  • Virtuel - c'est à l'héritier de décider
51
répondu Rinat Abdullin 2012-06-10 16:37:41

Fonction Abstraite:

  1. elle ne peut être déclarée que dans la classe abstraite.
  2. contient uniquement déclaration de la méthode pas à la mise en œuvre dans la classe abstraite.
  3. elle doit être remplacée dans la classe dérivée.

Fonction Virtuelle:

  1. elle peut être déclarée à l'intérieur de la classe abstraite ainsi que de la classe non abstraite.
  2. contient la méthode mise en œuvre.
  3. elle peut être annulée.
30
répondu Lexnim 2017-07-13 08:58:54

méthode abstraite: Si une classe contient une méthode abstraite, cette classe doit être déclarée 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 méthode virtuelle et fournir une logique supplémentaire, ou remplacer la logique avec votre propre mise en œuvre.

Quand utiliser quoi: Dans certains cas, vous savez que certains types devraient avoir une méthode spécifique, mais vous ne savez pas quelle implémentation cette méthode devrait avoir.

Dans de tels cas, vous pouvez créer une interface qui contient une méthode avec cette signature. Toutefois, si vous avez un tel cas, mais vous savez que des réalisateurs de cette interface devra é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 remplacée), et une autre méthode qui contient la logique "commune".

une méthode virtuelle doit ê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
répondu Frederik Gheysels 2009-04-16 09:03:07

explication: avec analogies. j'espère que ça va vous aider.

Contexte

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

FireEscape ()

  1. Ne pas récupérer leurs affaires
  2. à Pied à l'évacuation en cas d'incendie
  3. Marcher sur la construction de

il s'agit essentiellement d'une méthode virtuelle appelée FireEscape()

Méthode Virtuelle

ce plan est assez bon pour 99% des circonstances. C'est un régime de base qui fonctionne. Mais il y a 1% de chance que l'issue de secours soit bloquée ou endommagé, dans ce 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 outrepasser le plan de base FireEscape() avec votre propre version du plan:

  1. Courir à la fenêtre
  2. Sauter par la fenêtre
  3. Parachute de sécurité au fond

en d'autres termes les méthodes virtuelles fournissent une plan, qui peut être annulé si vous avez besoin de . Les sous-classes peuvent outrepasser la méthode virtuelle de la classe mère 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 générale d'évasion. Chaque homme est pour lui-même. De gestion ne sont intéressés que dans une telle politique existant.

en autres mots, chaque personne est forcé à développer sa propre méthode FireEscape (). Un gars sortira par l'escalier de secours. Un autre gars va parachute. Un autre gars va utiliser la technologie de propulsion de fusée pour s'envoler loin du bâtiment. Un autre gars va descendre en rappel. Gestion don't care comment vous échapper, aussi longtemps que vous avez une base FireEscape() plan - s'ils ne sont pas vous pouvez être assuré de la SST descendra sur l'organisation comme une tonne de briques. C'est qu'entend-on par une méthode abstraite.

Quelle est la différence entre les deux?

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

ce n'était pas le cas etait-il facile?

23
répondu BKSpurgeon 2017-05-02 07:53:07

une méthode abstraite est une méthode qui doit être mise en œuvre pour faire une classe concrète. La déclaration est dans la classe abstraite (et une classe avec une méthode abstraite doit être une classe abstraite) et il doit être mis en œuvre dans une classe concrète.

une méthode virtuelle est une méthode qui peut être dépassée dans une classe dérivée à l'aide du" override", remplaçant le comportement dans la superclasse. Si vous ne pas écraser, vous obtenez le comportement d'origine. Si vous le faites, vous obtenez toujours le nouveau comportement. Ceci s'oppose aux méthodes non virtuelles, qui ne peuvent pas être supplantées mais peuvent cacher la méthode originale. Ceci est fait en utilisant le modificateur new .

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 appelle SayHello , ou SayGoodbye , je reçois" Salut là-bas "et"à plus tard". Si j'appelle HelloGoodbye , Je reçois" bonjour "et"à plus tard". C'est parce que SayGoodbye est virtuel, et peut être remplacé par les classes dérivées. SayHello est seulement caché, donc quand je l'appelle de ma classe de base je reçois ma méthode originale.

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

21
répondu Kamiel Wanrooij 2011-11-16 03:01:06

les méthodes abstraites sont toujours virtuelles. Ils ne peuvent pas avoir de mise en œuvre.

C'est la différence principale.

fondamentalement, vous utiliserez une méthode virtuelle si vous avez l'implémentation "par défaut" de celui-ci et que vous voulez permettre aux descendants de changer son comportement.

avec une méthode abstraite, vous forcez les descendants à fournir une implémentation.

9
répondu Rashack 2012-06-10 16:39:38

j'ai simplifié cela en apportant quelques améliorations sur les classes suivantes (À partir d'autres réponses):

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");
        }
    }
}
9
répondu MeqDotNet 2012-06-10 16:46:59

Liaison est le processus de mappage d'un nom à une unité de code.

Late binding signifie que nous utilisons le nom, mais reportons la cartographie. En d'autres termes, nous créons/mentionnons le nom en premier, et laissons un processus ultérieur gérer la mise en correspondance du code à ce nom.

Maintenant, prendre en considération:

  • par rapport aux humains, les machines sont vraiment bonnes pour la recherche et le tri
  • comparé aux machines, les humains sont vraiment bons à l'invention et à l'innovation

ainsi, la réponse courte est: virtual est une instruction de fixation tardive pour la machine (runtime) tandis que abstract est l'instruction de fixation tardive pour l'homme (programmeur)

en d'autres termes, virtual signifie:

Chers runtime , lier le code approprié à ce nom en faisant ce que vous faites de mieux: recherche "

alors que abstract signifie:

Chers programmeur , veuillez lier le code approprié à ce nom en faisant ce que vous faites de mieux: inventer "

Par souci d'exhaustivité, surcharge signifie:

Chers compilateur , lier le code approprié pour ce nom en faisant ce que vous faites le mieux: tri ".

4
répondu Rodrick Chapman 2018-02-01 19:29:34

vous utilisez essentiellement une méthode virtuelle lorsque vous voulez que les héritiers étendre la fonctionnalité si ils le veulent.

vous utilisez des méthodes abstraites quand vous voulez que les héritiers mettent en œuvre la fonctionnalité (et dans ce cas, ils n'ont pas le choix)

3
répondu Brann 2009-04-16 09:02:26

j'ai vu dans certains endroits, la méthode abstraite est défini comme ci-dessous. **

"Une Méthode Abstraite doit avoir à mettre en œuvre dans la classe enfant"

** J'ai senti que c'est comme .

il n'est pas nécessaire qu'une méthode abstraite doive être implémentée dans une classe enfant, si la classe enfant est aussi abstraite ..

1)Une méthode abstraite cant être une méthode privée. 2) une méthode abstraite cant doit être implémentée dans la même classe abstraite.

je dirais ..si nous implémentons une classe abstraite, vous devez avoir à outrepasser les méthodes abstraites de la classe abstract de base. Parce.. La mise en œuvre de la méthode abstraite se fait avec override key word .Similaire à la méthode Virtuelle.

Il est pas nécessaire pour qu'une méthode virtuelle soit implémentée dans une classe héritée.

                                 ----------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();
    }
}
3
répondu Kodoth 2016-03-23 22:18:56

Méthode Virtuelle :

  • virtuel signifie que nous pouvons l'annuler.

  • la fonction virtuelle a une implémentation. Quand nous héritons de la classe nous peut outrepasser la fonction virtuelle et fournir notre propre logique.

  • nous pouvons changer le type de retour de la fonction virtuelle tout en mettant en œuvre le

    fonction dans la classe fille(qui peut être dit comme un concept de

    Filature).

Méthode Abstraite

  • abstrait signifie que nous devons l'annuler.

  • une fonction abstraite n'a pas de mise en œuvre et doit être dans une classe abstraite.

  • il ne peut que être déclaré. Cela force la classe dérivée à en assurer la mise en œuvre.

  • un membre abstrait est implicitement virtuel. L'abstrait peut être appelé virtuel pur dans certaines langues.

    public abstract class BaseClass
    { 
        protected abstract void xAbstractMethod();
    
        public virtual void xVirtualMethod()
        {
            var x = 3 + 4;
        }
    } 
    
3
répondu flik 2018-03-28 20:31:09

Résumé de la fonction ne peut pas avoir un corps et qui DOIVENT être remplacées par les classes enfant

Fonction Virtuelle aura un corps et peut ou ne peut pas être remplacée par des enfants des classes

2
répondu Yeasin Abedin Siam 2016-01-12 17:17:10

la plupart des exemples ci - dessus utilisent le code-et ils sont très bons. Je n'ai pas besoin d'ajouter à ce qu'ils disent, mais ce qui suit est une explication simple qui utilise des analogies plutôt que des termes de code/technique.

Explication Simple - Explication en utilisant des analogies

Méthode Abstraite

Pense George W. Bush. Il dit à ses soldats: "allez vous battre en Irak". Et c'est tout. Tout ce qu'il a spécifié, c'est que les combats doivent être faits. Il ne spécifie pas comment exactement ce qui arrivera. Mais je veux dire, vous ne pouvez pas simplement sortir et de "lutte": ça signifie quoi exactement? je me bats avec un b-52 ou mon derringer? Ces détails sont laissés à quelqu'un d'autre. C'est une méthode abstraite.

Méthode Virtuelle

David Petraeus est haut dans l'armée. Il a défini ce que le combat signifie:

  1. trouver l'ennemi
  2. neutralisez-le.
  3. boire une bière après

le problème est qu'il s'agit d'une méthode très générale. C'est une bonne méthode qui fonctionne, mais parfois n'est pas assez précis. La bonne chose pour Petraeus est que ses ordres ont la marge de manœuvre et la portée - il a permis à d'autres de changer sa définition de "combat", en fonction de leurs besoins particuliers.

les blogs de Job privés lit L'ordre de Petraeus et est autorisé à mettre en œuvre sa propre version de combat, selon ses exigences particulières:

  1. trouver ennemi.
  2. tirez-lui dans la tête.
  3. Rentrer À La Maison
  4. prenez de la bière.

Nouri al Maliki reçoit également les mêmes ordres de Petraeus. Il est de se battre aussi. Mais il est un politicien, pas un d'infanterie de l'homme. Il est évident qu'il ne peut pas tourner autour de la tête en tirant sur ses ennemis politiques. Parce que Petraeus lui a donné une méthode virtuelle, alors Maliki peut mettre en œuvre sa propre version de la méthode de combat, selon ses circonstances particulières:

  1. trouver ennemi.
  2. faites-le arrêter avec des accusations fabriquées de toutes pièces.
  3. Rentrer À La Maison
  4. prenez de la bière.

IN d'autres termes, une méthode virtuelle fournit des instructions standard - mais ce sont des instructions générales, qui peuvent être plus spécifique par des gens en bas de la hiérarchie de l'armée, en fonction de leurs circonstances particulières.

la différence entre les deux

  • George Bush de ne pas révéler les détails d'implémentation. Il doit être fourni par quelqu'un d'autre. C'est une méthode abstraite.

  • Petraeus d'un autre côté does fournir des détails de mise en œuvre, mais il a donné la permission à ses subordonnés pour outrepasser ses ordres avec leur propre version, s'ils peuvent venir avec quelque chose de mieux.

espère que ça aide.

2
répondu BKSpurgeon 2016-05-06 00:55:57

fonction abstraite (méthode):

● Une méthode abstraite est une méthode qui est déclarée avec le mot clé abstract.

● Il n'a pas de corps.

● Il devrait être mis en œuvre par la classe dérivée.

● Si une méthode est abstraite, puis la classe abstraite.

fonction virtuelle (méthode) :

● Une méthode virtuelle est la méthode qui est déclarée avec le mot-clé virtuel et il peut être dépassé par la méthode de classe dérivée en utilisant le mot-clé override.

● C'est à la classe dérivée que de le remplacer ou non.

2
répondu Kedarnath M S 2018-01-26 08:11:03

la réponse a été fournie plusieurs fois, mais la question de savoir quand utiliser chacune d'elles est une décision de durée de conception. Je considérerais comme une bonne pratique d'essayer de regrouper les définitions de méthodes communes en interfaces distinctes et de les intégrer dans des classes aux niveaux d'abstraction appropriés. Le Dumping d'un ensemble commun de définitions de méthodes abstraites et virtuelles dans une classe rend la classe unistantiable quand il peut être préférable de définir une classe non abstraite qui met en œuvre un ensemble d'interfaces concises. Comme toujours, cela dépend de ce qui convient le mieux à vos besoins spécifiques.

1
répondu ComeIn 2013-08-19 10:28:31

vue générale orientée objet:



en ce qui concerne la méthode abstraite : quand vous mettez une méthode abstraite dans la classe des parents en fait vous dites aux classes d'enfants: Hey notez que vous avez une signature de méthode comme celle-ci. Et si vous voulez l'utiliser vous devez mettre en place votre propre!



en ce qui concerne la fonction virtuelle : quand vous mettez un virtuel méthode dans la classe parent vous dites aux classes dérivées: Hey il y a une fonctionnalité ici qui fait quelque chose pour vous. Si cela est utile pour vous juste à l'utiliser. Sinon, outrepassez ceci et implémentez votre code, même vous pouvez utiliser mon implémentation dans votre code !



il s'agit d'une certaine philosophie sur la différence entre ces deux concepts en général oo

1
répondu Mohammad Nikravesh 2017-03-01 10:35:20

Il n'y a rien d'appel virtuel de la classe en C#.

pour fonctions

  1. fonction abstraite n'ont que la signature seulement,la classe de lecteur devrait outrepasser avec la fonctionnalité.
  2. "151950920 Virtuel de la fonction de tenir la partie de la fonctionnalité de la classe lecteur peut ou ne peut pas le remplacer en fonction de l'exigence

vous pouvez décider avec votre exigence.

1
répondu Nithila Shanmugananthan 2018-04-28 14:29:30

méthode abstraite n'a pas d'implémentation.Il est déclaré dans la classe des parents. La classe des enfants est responsable de la mise en œuvre de cette méthode.

méthode virtuelle devrait avoir une mise en œuvre dans la classe des parents et il facilite la classe de l'enfant de faire le choix d'utiliser cette mise en œuvre de la classe des parents ou d'avoir une nouvelle mise en œuvre pour lui-même pour cette méthode dans la classe de l'enfant.

0
répondu Vinay Chanumolu 2018-06-05 12:38:45

une fonction abstraite est" juste " une signature, sans implémentation. Il est utilisé dans une interface de déclarer comment la classe peut être utilisée. Elle doit être implémentée dans l'une des classes dérivées.

fonction virtuelle (méthode en fait), est une fonction que vous déclarez aussi, et devrait être implémentée dans une des classes de la hiérarchie de l'héritage.

les instances héritées d'une telle classe héritent aussi de l'implémentation, à moins que vous ne l'implémentiez, dans une classe hiérarchique inférieure.

0
répondu Sagi Berco 2018-07-27 11:07:41

à mon entendement:

Méthodes Abstraites:

Seule la classe abstraite peut contenir des méthodes abstraites. Aussi la classe dérivée besoin de mettre en œuvre la méthode et aucune mise en œuvre n'est fournie dans la classe.

Méthodes Virtuelles:

une classe peut déclarer ceux-ci et aussi fournir la mise en œuvre de la même. Aussi la classe dérivée a besoin d'implémenter de la méthode pour la surpasser.

-2
répondu Qaiser 2011-06-27 16:59:14