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

1578

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

Moran Helman
la source
271
Une fonction abstraite doit être remplacée tandis qu'une fonction virtuelle peut être remplacée.
Jordan Parmer
15
Les fonctions virtuelles peuvent avoir une implémentation par défaut / générique dans la classe de base.
Martin
5
Le mot clé ici est abstrait ; Ils n'existent pas et ne sont qu'une vague idée de ce qu'est la fonction (signature de la méthode)
Cole Johnson

Réponses:

2733

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

Une fonction virtuelle , dit essentiellement look, voici les fonctionnalités qui peuvent ou non être assez bonnes pour la classe enfant. Donc, si c'est assez bon, utilisez cette méthode, sinon, remplacez-moi et fournissez vos propres fonctionnalités.

BFree
la source
396
Et bien sûr, si vous surchargez une méthode virtuelle, vous pouvez toujours vous référer à la méthode parent en appelant base.Foo (...)
Brann
196
Merci. Il s'agit d'une explication bien meilleure et plus simple que tout ce qui se trouve dans la documentation MSDN (j'ai eu mal à la tête après cinq minutes de lecture: msdn.microsoft.com/en-us/library/aa645767(v=vs.71).aspx )
Jake
15
Venant de Java, j'étais un peu perplexe sur la raison pour laquelle nous devons le rendre virtuel, jusqu'à ce que je lise ceci: stackoverflow.com/a/1062126/193634
Rosdi Kasim
4
@MeqDotNet Cela signifie que si vous aimez mon implémentation, utilisez-moi sinon écrivez le vôtre mieux que moi :)
Usman Younas
16
Cela devrait être dans la bibliothèque de référence Microsoft que j'ai passé 10 minutes à lire et toujours confus.
SamChen
303

Une fonction abstraite n'a pas d'implémentation 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 elle peut exister sur une classe abstraite ou une classe non 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();
}
JoshBerke
la source
28
Très utile pour voir un exemple de code - aide à rendre les différentes explications dans les réponses beaucoup plus claires.
Simon Tewsi
2
J'ai annulé la réponse à la version précédente: les deux classes ne sont que des exemples, la première classe se compilera car elle est marquée comme abstraite, la seconde ne le sera pas. Que MyBase hérite d'une autre classe ou non n'a pas d'importance.
Dirk
2
Votre MyBaseclasse n'a- t-elle pas à implémenter la classe abstraite , d'une manière ou d'une autre? Je ne fais pas ça souvent, donc je peux me tromper. Je ne vois pas cela dans votre exemple.
jp2code
2
Dans l'exemple ci-dessus, MyBase montre ce que vous ne pouvez pas faire. Autrement dit, vous ne pouvez pas avoir une méthode abstraite dans une classe non abstraite
JoshBerke
80
  1. Seules les abstractclasses peuvent avoir des abstractmembres.
  2. Une non- abstractclasse qui hérite d'une abstractclasse doit override ses abstractmembres.
  3. Un abstractmembre l'est implicitement virtual.
  4. Un abstractmembre ne peut fournir aucune implémentation ( abstractest appelé pure virtualdans certaines langues).
Mehrdad Afshari
la source
Le numéro 3 n'a pas de sens pour moi. Je pense que vous vouliez dire "Un membre d'une classe abstraite est implicitement virtuel" (c'est-à-dire que vous pouvez lui fournir des fonctionnalités sans avoir à spécifier qu'il est virtuel).
Hobo Spider
5
Non, je voulais dire précisément ce que j'ai écrit. Un membre d'une classe abstraite peut être virtualou non virtual. Un abstractmembre (c'est-à-dire une propriété abstraite, une méthode abstraite) est comme une méthode virtuelle, c'est-à-dire que vous pouvez la remplacer, sauf qu'elle ne comporte pas avec elle une implémentation par défaut.
Mehrdad Afshari
"Le membre abstrait est" implicitement "virtuel". Mais j'ai vu quelque part, quelqu'un avait créé des membres abstraits en ajoutant explicitement un mot clé "virtuel". Ce qui n'est pas nécessaire et en fait cela m'a donné un doute jusqu'à ce que je lise votre réponse.
bonCodigo
Veuillez inclure les références de support pour le point 4. Et votre message n'apporte rien d'autre que les précédents.
Rafael
Il s'agit simplement d'un tas de déclarations sans explication.
Reverse Engineered
61

Vous devez toujours remplacer une fonction abstraite.

Donc:

  • Fonctions abstraites - lorsque l'héritier doit fournir sa propre implémentation
  • Virtuel - quand c'est à l'héritier de décider
Rinat Abdullin
la source
37

Fonction abstraite:

  1. Il ne peut être déclaré qu'à l'intérieur d'une classe abstraite.
  2. Il contient uniquement la déclaration de méthode et non 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é à l'intérieur d'une classe abstraite ou non abstraite.
  2. Il contient l'implémentation de la méthode.
  3. Il peut être annulé.
Lexnim
la source
29

Méthode abstraite: lorsqu'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 remplacer la méthode virtuelle et fournir une logique supplémentaire, ou remplacer la logique par votre propre implémentation.

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

Frederik Gheysels
la source
29

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

Le contexte

Je travaille au 21e é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 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 récupérez pas vos affaires
  2. Marcher jusqu'à un escalier de secours
  3. Sortez du bâtiment

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 plan de base qui fonctionne. Mais il y a 1% de chances que l'escalier de secours soit bloqué ou endommagé, auquel cas vous êtes complètement vissé 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 FireEscape () de base par votre propre version du plan:

  1. Run to window
  2. Sautez 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 annulé si nécessaire . Les sous-classes peuvent remplacer la méthode virtuelle de la classe parent si le programmeur le juge approprié.

Méthodes abstraites

Toutes les organisations ne sont pas bien entraînées. Certaines organisations ne font pas d'exercices d'incendie. Ils n'ont pas de politique d'évasion globale. Chaque homme est pour lui-même. La direction ne s'intéresse qu'à une telle politique.

En d'autres termes, chaque personne est obligée de développer sa propre méthode FireEscape (). Un gars sortira de l'escalier de secours. Un autre gars va parachuter. Un autre gars utilisera la technologie de propulsion des fusées pour s'éloigner du bâtiment. Un autre gars va descendre en rappel. La direction ne se soucie pas de la façon dont vous vous échappez, tant que vous avez un plan FireEscape () de base - si ce n'est pas le cas, vous pouvez être assuré que la SST tombera sur l'organisation comme une tonne de briques. C'est ce que l'on entend par une méthode abstraite.

Quelle est encore la différence entre les deux?

Méthode abstraite: les sous-classes sont obligées d'implémenter leur propre méthode FireEscape. Avec une méthode virtuelle, vous avez un plan de base qui vous attend, mais pouvez choisir de mettre en œuvre le vôtre s'il n'est pas assez bon.

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

BKSpurgeon
la source
22

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 elle doit être implémentée dans une classe concrète.

Une méthode virtuelle est une méthode qui peut être remplacée dans une classe dérivée à l'aide du remplacement, remplaçant le comportement dans la superclasse. Si vous ne remplacez pas, vous obtenez le comportement d'origine. 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 peuvent masquer la méthode d'origine. Cela se fait à l'aide du 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");
    }
}

Lorsque j'instancie DerivedClasset que j'appelle SayHello, ou SayGoodbye, je reçois "Salut" et "A plus tard". Si j'appelle HelloGoodbye, je reçois "Bonjour" et "A plus tard". En effet, il SayGoodbyeest virtuel et peut être remplacé par des classes dérivées. SayHelloest seulement caché, donc quand j'appelle ça depuis ma classe de base, j'obtiens ma méthode d'origine.

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

Kamiel Wanrooij
la source
9

Les méthodes abstraites sont toujours virtuelles. Ils ne peuvent pas avoir d'implémentation.

Voilà la principale différence.

Fondamentalement, vous utiliseriez une méthode virtuelle si vous en avez l'implémentation par défaut et que vous souhaitez autoriser les descendants à modifier son comportement.

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

Rashack
la source
9

J'ai simplifié cela en apportant quelques améliorations aux 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");
        }
    }
}
MeqDotNet
la source
6

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

La liaison tardive signifie que nous utilisons le nom, mais reportons le mappage. En d'autres termes, nous créons / mentionnons d'abord le nom et laissons un processus ultérieur gérer le mappage du code avec ce nom.

Considérez maintenant:

  • Par rapport aux humains, les machines sont vraiment douées pour rechercher et trier
  • Comparé aux machines, les humains sont vraiment bons en invention et en innovation

Donc, la réponse courte est: virtualest une instruction de liaison tardive pour la machine (runtime) alors que abstractest l'instruction de liaison tardive pour l'humain (programmeur)

En d'autres termes, virtualsignifie:

"Cher runtime , liez le code approprié à ce nom en faisant ce que vous faites le mieux: la recherche "

Alors que abstractsignifie:

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

Par souci d'exhaustivité, la surcharge signifie:

"Cher compilateur , liez le code approprié à ce nom en faisant ce que vous faites le mieux: le tri ".

Rodrick Chapman
la source
3

Vous utilisez essentiellement une méthode virtuelle lorsque vous souhaitez que les héritiers étendent les fonctionnalités s'ils le souhaitent.

Vous utilisez des méthodes abstraites lorsque vous souhaitez que les héritiers implémentent la fonctionnalité (et dans ce cas, ils n'ont pas le choix)

Brann
la source
3

Méthode virtuelle :

  • Virtuel signifie que nous POUVONS l'emporter.

  • Virtual Function a une implémentation. Lorsque nous héritons de la classe, nous pouvons remplacer la fonction virtuelle et fournir notre propre logique.

  • Nous pouvons changer le type de retour de la fonction virtuelle lors de l'implémentation du
    fonction dans la classe enfant (ce qui peut être dit comme un concept de
    Shadowing).

Méthode abstraite

  • Abstrait signifie que nous devons le remplacer.

  • Une fonction abstraite n'a pas d'implémentation et doit être dans une classe abstraite.

  • Elle ne peut être déclarée. Cela oblige la classe dérivée à en fournir l'implémentation.

  • Un membre abstrait est implicitement virtuel. L'abrégé peut être qualifié de pur virtuel dans certaines langues.

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

J'ai vu à certains endroits la méthode abstraite est définie comme ci-dessous. **

"Une méthode abstraite doit avoir à implémenter dans la classe enfant"

** J'ai senti que c'était comme.

Il n'est pas nécessaire qu'une méthode abstraite soit implémentée dans une classe enfant, si la classe enfant est également abstraite .

1) Une méthode abstraite ne peut pas être une méthode privée. 2) Une méthode abstraite ne peut pas être mise en œuvre dans la même classe abstraite.

Je dirais que si nous implémentons une classe abstraite, vous devez remplacer les méthodes abstraites de la classe abstraite de base. Parce que .. L'implémentation de la méthode abstraite est avec un mot clé de remplacement .Similaire à la méthode virtuelle.

Il n'est pas nécessaire 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();
    }
}
Kod
la source
2

La plupart des exemples ci-dessus utilisent du code - et ils sont très 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 codes / termes techniques.

Explication simple - Explication utilisant des analogies

Méthode abstraite

Pensez à George W. Bush. Il dit à ses soldats: "Allez combattre en Irak". Et c'est tout. Tout ce qu'il a précisé, c'est que les combats doivent être faits. Il ne précise pas exactement comment cela se produira. Mais je veux dire, vous ne pouvez pas simplement sortir et "combattre": qu'est-ce que cela signifie exactement? dois-je me battre avec un B-52 ou mon derringer? Ces détails spécifiques sont laissés à quelqu'un d'autre. Il s'agit d'une méthode abstraite.

Méthode virtuelle

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

  1. Trouvez l'ennemi
  2. Neutralisez-le.
  3. Prenez une bière après

Le problème est que c'est une méthode très générale. C'est une bonne méthode qui fonctionne, mais qui n'est parfois pas assez spécifique. Une bonne chose pour Petraeus est que ses ordres ont une marge de manœuvre et une portée - il a permis à d'autres de changer sa définition de "combat", selon leurs exigences particulières.

Private Job Bloggs lit l'ordre de Petraeus et est autorisé à implémenter sa propre version de combat, selon ses besoins particuliers:

  1. Trouvez l'ennemi.
  2. Lui tirer dans la tête.
  3. Rentrer chez soi
  4. Prenez de la bière.

Nouri al Maliki reçoit également les mêmes ordres de Petraeus. Il doit aussi se battre. Mais c'est un homme politique, pas un fantassin. De toute évidence, il ne peut pas tirer sur ses ennemis politiques dans la tête. Parce que Petraeus lui a donné une méthode virtuelle, Maliki peut implémenter sa propre version de la méthode de combat, selon ses circonstances particulières:

  1. Trouvez l'ennemi.
  2. Faites-le arrêter avec des accusations contrefaites.
  3. Rentrer chez soi
  4. Prenez de la bière.

En d'autres termes, une méthode virtuelle fournit des instructions standard, mais ce sont des instructions générales, qui peuvent être précisées par des personnes de la hiérarchie militaire, en fonction de leur situation particulière.

La différence entre les deux

  • George Bush ne prouve aucun détail de mise en œuvre. Cela doit être fourni par quelqu'un d'autre. Il s'agit d'une méthode abstraite.

  • Petraeus d'autre part ne fournir des détails de mise en œuvre , mais il a donné l' autorisation de ses subordonnés de passer outre ses ordres avec leur propre version, si elles peuvent venir avec quelque chose de mieux.

J'espère que cela pourra aider.

BKSpurgeon
la source
2

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 doit être implémenté par la classe dérivée.

● Si une méthode est abstraite, la classe doit être abstraite.

fonction virtuelle (méthode):

● Une méthode virtuelle est la méthode qui est déclarée avec le mot clé virtual et elle peut être remplacée par la méthode de classe dérivée à l'aide du mot clé override.

● Il appartient à la classe dérivée de la remplacer ou non.

Kedarnath MS
la source
1

La réponse a été fournie à plusieurs reprises, mais la question de savoir quand les utiliser est une décision au moment de la conception. Je considérerais comme une bonne pratique d'essayer de regrouper les définitions de méthodes communes dans des interfaces distinctes et de les regrouper en classes aux niveaux d'abstraction appropriés. Le vidage d'un ensemble commun de définitions de méthodes abstraites et virtuelles dans une classe rend la classe impossible à établir quand il peut être préférable de définir une classe non abstraite qui implémente un ensemble d'interfaces concises. Comme toujours, cela dépend de ce qui convient le mieux aux besoins spécifiques de vos applications.

Entrez
la source
1

La fonction abstraite ne peut pas avoir de corps et DOIT être remplacée par les classes enfants

La fonction virtuelle aura un corps et pourra ou non être remplacée par les classes enfants

Yeasin Abedin Siam
la source
1

De la vue orientée objet générale:

Concernant la méthode abstraite : Lorsque vous mettez une méthode abstraite dans la classe parent, vous dites en fait aux classes enfants: Hé, notez que vous avez une signature de méthode comme celle-ci. Et si vous voulez l'utiliser, vous devez implémenter le vôtre!

Concernant la fonction virtuelle : Lorsque vous mettez une méthode virtuelle dans la classe parent, vous dites aux classes dérivées: Hé, il y a une fonctionnalité ici qui fait quelque chose pour vous. Si cela vous est utile, utilisez-le. Sinon, remplacez cela et implémentez votre code, même vous pouvez utiliser mon implémentation dans votre code!

ceci est une philosophie sur différent entre ces deux concept dans General OO

Mohammad Nikravesh
la source
1

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

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

Les instances héritées d'une telle classe héritent également de l'implémentation, sauf si vous l'implémentez, dans une classe de hiérarchie inférieure.

Sagi Berco
la source
1

Si une classe dérive de cette classe abstraite, elle est alors forcée de remplacer le membre abstrait. Ceci est différent du modificateur virtuel, qui spécifie que le membre peut éventuellement être remplacé.

x-rw
la source
0

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

Pour les fonctions

  1. La fonction abstraite n'a qu'une signature uniquement, la classe de lecteur doit remplacer la fonctionnalité.
  2. La fonction virtuelle contiendra la partie de la fonctionnalité que la classe de lecteur peut ou ne peut pas remplacer en fonction de l'exigence

Vous pouvez décider avec votre condition.

Nithila Shanmugananthan
la source
0

La méthode abstraite n'a pas d'implémentation, elle est déclarée dans la classe parente. La classe enfant est responsable de l'implémentation de cette méthode.

La méthode virtuelle doit avoir une implémentation dans la classe parent et elle facilite la classe enfant pour faire le choix d'utiliser cette implémentation de la classe parent ou d'avoir une nouvelle implémentation pour elle-même pour cette méthode dans la classe enfant.

Vinay Chanumolu
la source
0

À partir d'un arrière-plan C ++, C # virtuel correspond à C ++ virtuel, tandis que les méthodes abstraites C # correspondent à la fonction virtuelle pure C ++

Yituo
la source
0

Une fonction ou une méthode abstraite est un "nom d'opération" public exposé par une classe, son but, avec les classes abstraites, est principalement de fournir une forme de contrainte dans la conception d'objets par rapport à la structure qu'un objet doit implémenter.

En fait, les classes qui héritent de sa classe abstraite doivent donner une implémentation à cette méthode, généralement les compilateurs génèrent des erreurs quand ils ne le font pas.

L'utilisation de classes et de méthodes abstraites est importante surtout pour éviter qu'en se concentrant sur les détails d'implémentation lors de la conception des classes, la structure des classes soit trop liée aux implémentations, créant ainsi des dépendances et un couplage entre les classes qui collaborent entre elles.

Une fonction ou méthode virtuelle est simplement une méthode qui modélise un comportement public d'une classe, mais que nous pouvons laisser libre de le modifier dans la chaîne d'héritage, car nous pensons que les classes enfants pourraient avoir besoin d'implémenter des extensions spécifiques pour ce comportement.

Ils représentent tous deux une forme de polymorphe dans le paradigme d'orientation d'objet.

Nous pouvons utiliser des méthodes abstraites et des fonctions virtuelles ensemble pour prendre en charge un bon modèle d'héritage.

Nous concevons une bonne structure abstraite des principaux objets de notre solution, puis créons des implémentations de base en localisant celles plus sujettes à d'autres spécialisations et nous les rendons virtuelles, enfin nous spécialisons nos implémentations de base, éventuellement «écrasantes» les héritées virtuelles.

Ciro Corvino
la source
0

Ici, j'écris un exemple de code en espérant que cela puisse être un exemple assez tangible pour voir les comportements des interfaces, des classes abstraites et des classes ordinaires à un niveau très basique. Vous pouvez également trouver ce code dans github en tant que projet si vous souhaitez l'utiliser comme démo: 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
la source
-4

À ma connaissance:

Méthodes abstraites:

Seule la classe abstraite peut contenir des méthodes abstraites. La classe dérivée doit également implémenter la méthode et aucune implémentation n'est fournie dans la classe.

Méthodes virtuelles:

Une classe peut les déclarer et fournir également leur implémentation. La classe dérivée doit également implémenter la méthode pour la remplacer.

Qaiser
la source