Question

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

Était-ce utile?

La solution

Une fonction abstraite ne peut pas avoir la fonctionnalité. Vous dites essentiellement, une classe enfant DOIT donner leur propre version de cette méthode, mais il est trop général pour essayer même de mettre en œuvre dans la classe parente.

Une fonction virtuelle , revient à dire regarder, voici la fonctionnalité qui peuvent ou peuvent ne pas être assez bon pour la classe enfant. Donc, s'il est assez bon, utiliser cette méthode, sinon, me remplacer, et de fournir vos propres fonctionnalités.

Autres conseils

Une fonction abstraite n'a pas implemention et il ne peut être déclaré sur une classe abstraite. Cela force la classe dérivée de fournir une mise en œuvre.

Une fonction virtuelle fournit une implémentation par défaut et il peut exister soit 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();
}
  1. Seules les classes de abstract peuvent avoir des membres de abstract.
  2. Une classe non abstract qui hérite d'une classe de abstract doit override ses membres abstract.
  3. Un membre abstract est implicitement virtual.
  4. Un membre abstract ne peut fournir aucune mise en œuvre (abstract est appelé pure virtual dans certaines langues).

Vous devez toujours passer outre une fonction abstraite.

Ainsi:

  • fonctions Résumé - lorsque doit fournir son héritier propre implémentation
  • Virtual - lorsque il appartient à l'héritière de décider

Résumé Fonction:

  1. Il peut être déclaré qu'à l'intérieur de la classe abstraite.
  2. Il ne contient que déclaration de méthode et non la mise en œuvre en classe abstraite.
  3. Il doit être redéfinie dans la classe dérivée.

Fonction virtuelle:

  1. Il peut être déclaré à l'intérieur abstrait, ainsi que la classe non abstraite.
  2. Il contient la mise en œuvre de la méthode.
  3. Il peut être redéfinie.

Procédé Résumé: Lorsqu'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, doit fournir une implémentation de cette méthode abstraite.

Méthode virtuelle: Une classe peut avoir une méthode virtuelle. La méthode virtuelle a une mise en œuvre. Lorsque vous héritez d'une classe qui a une méthode virtuelle, vous peut remplacer la méthode virtuelle et fournir une logique supplémentaire, ou remplacer la logique avec votre propre implémentation.

Quand utiliser ce: Dans certains cas, vous savez que certains types devraient avoir une méthode spécifique, mais vous ne savez pas ce que la mise en œuvre de cette méthode devrait avoir.
Dans ce 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 implementors cette interface aussi une autre méthode commune (pour lequel vous pouvez déjà fournir la mise en œuvre), vous pouvez créer une classe abstraite. Cette classe abstraite contient alors la méthode abstraite (qui doit être outrepassée), et une autre méthode qui contient la logique « commune ».

Une méthode virtuelle doit être utilisé si vous avez une classe qui peut être utilisé directement, mais pour lequel vous voulez être en mesure d'héritières de changer certains comportements, bien qu'il ne soit pas obligatoire.

explication: avec des analogies. espérons qu'il vous aidera.

Contexte

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

FireEscape ()

  1. Ne pas recueillir de biens
  2. Marche pour échapper à feu
  3. Sortez de la construction

Ceci est essentiellement une méthode virtuelle appelée FireEscape ()

Méthode virtuelle

Ce plan est assez bon pour 99% des cas. Il est un plan de base qui fonctionne. Mais il y a une chance de 1% que la fuite de feu est bloqué ou endommagé dans ce cas, vous êtes complètement défoncée et vous deviendrez des toasts sauf si vous prenez des mesures drastiques. Avec des méthodes virtuelles que vous pouvez faire tout cela: vous pouvez remplacer le plan FireEscape () de base avec votre propre version du plan:

  1. Exécuter à la fenêtre
  2. sauter par la fenêtre
  3. Parachute en toute sécurité au fond

En d'autres termes méthodes virtuelles fournissent un plan de base, qui peut être outrepassée si vous avez besoin . Les sous-classes peuvent remplacer la méthode virtuelle de la classe parent si le programmeur juge approprié.

Les méthodes abstraites

Toutes les organisations sont bien forés. Certaines organisations ne font pas des exercices d'incendie. Ils ne disposent pas d'une politique globale d'évasion. Tout homme est pour lui-même. La gestion ne sont intéressés par une telle politique existante.

En d'autres termes, chaque personne est forcé pour développer sa propre méthode FireEscape (). Un gars va sortir l'évasion de feu. Un autre gars va sauter en parachute. Un autre gars utilisera la technologie de propulsion de fusée pour voler loin du bâtiment. Un autre gars va descendre en rappel sur. Gestion ne se soucient pas comment vous échapper, tant que vous avez un plan FireEscape () de base - si elles ne le font pas, vous pouvez être assuré en matière de SST descendra 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 à nouveau?

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

Maintenant, ce n'était pas si dur était-il?

Une méthode abstraite est une méthode qui doit être mis 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 substituée dans une classe dérivée en utilisant la commande prioritaire, remplacement le comportement de la classe mère. Si vous ne remplacez pas, vous obtenez le comportement d'origine. Si vous le faites, vous obtenez toujours le nouveau comportement. Cette opposition à des méthodes non virtuelles, qui ne peuvent être surchargées, mais peut 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'instancier DerivedClass et SayHello d'appel ou SayGoodbye, je reçois « Salut là » et « Voyez-vous plus tard ». Si je l'appelle HelloGoodbye, je reçois « Bonjour » et « Voyez-vous plus tard ». En effet, SayGoodbye est virtuel, et peut être remplacé par des classes dérivées. SayHello n'est caché, quand j'appelle cela de ma classe de base je reçois ma méthode originale.

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

Les méthodes abstraites sont toujours virtuel. Ils ne peuvent pas avoir une mise en œuvre.

C'est la principale différence.

En gros, vous devez utiliser une méthode virtuelle si vous avez la mise en œuvre « par défaut » de celui-ci et que vous voulez permettre à des descendants de changer son comportement.

Avec une méthode abstraite, vous obligez les descendants de fournir une mise en œuvre.

Je l'ai fait plus simple en faisant quelques améliorations sur les classes suivantes (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");
        }
    }
}

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

La liaison tardive signifie que nous utilisons le nom, mais reportons la mise en correspondance. En d'autres termes, nous créons / mentionner d'abord le nom, et laissez un processus ultérieur gérer le mappage de code à ce nom.

Considérons maintenant:

  • Par rapport à l'homme, les machines sont vraiment bien à la recherche et le tri
  • Par rapport aux machines, les humains sont vraiment bien à l'invention et l'innovation

Alors, la réponse est: virtual est une instruction liaison tardive de la machine (exécution) alors que abstract est la fin instruction de liaison pour l'être humain (programmeur)

En d'autres termes, virtual signifie:

« Cher runtime , lier le code approprié à ce nom en faisant ce que vous faites le mieux: recherche »

Alors que signifie abstract:

« Cher programmeur , s'il vous plaît lier le code approprié à ce nom en faisant ce que vous faites le mieux: inventant »

Par souci d'exhaustivité, surcharge signifie:

« Cher compilateur , lier le code approprié à ce nom en faisant ce que vous faites le mieux: tri ».

Vous utilisez essentiellement une méthode virtuelle lorsque vous voulez que les héritières d'étendre la fonctionnalité si elles veulent.

Vous utilisez des méthodes abstraites quand vous voulez les mettre en œuvre la héritières des fonctionnalités (et dans ce cas ils ont pas d'autre choix)

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

  

"Une méthode abstraite doit avoir à mettre en œuvre dans la classe des enfants"

** Je me sentais comme il est.

Il est pas nécessaire qu'une méthode abstraite doit être mis en œuvre dans une classe d'enfants, si la classe enfant est aussi abstraite ..

1) Une méthode abstraite cant une méthode privée. 2) Une méthode abstraite cant être mis en œuvre dans la même classe abstraite.

Je dirais que ..si nous mettons en place une classe abstraite, vous devez avoir à remplacer les méthodes abstraites de la classe abstraite base. Parce que .. La mise en œuvre de la méthode abstraite est avec override touche mot .Similar à la méthode virtuelle.

Il ne faut pas une méthode virtuelle à mettre en œuvre 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();
    }
}

Méthode virtuelle :

  • moyens virtuels nous pouvons remplacer.

  • Fonction virtuelle a une mise en œuvre. Lorsque nous héritons la classe nous peut remplacer la fonction virtuelle et de fournir notre propre logique.

  • Nous pouvons changer le type de retour de la fonction virtuelle en mettant en œuvre le
    fonction de la classe de l'enfant (qui peut être dit en tant que concept de
    Shadowing).

Résumé Méthode

  • Résumé signifie que nous devons remplacer.

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

  • Il ne peut être déclarée. Cela force la classe dérivée de fournir la mise en œuvre de celui-ci.

  • Un membre abstrait est implicitement virtuel. Le résumé peut être appelé comme virtuel pur dans certaines des langues.

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

Fonction Résumé ne peut pas avoir un corps et doit être remplacée par les classes d'enfants

Fonction virtuelle aura un corps et peut ou non être supplantée par les classes enfants

La plupart des exemples ci-dessus utilisent le code - et ils sont très très bon. Je ne ai pas ajouter à ce qu'ils disent, mais ce qui suit est une explication simple qui utilise des analogies plutôt qu'en termes de code / techniques.

Simple Explication - Explication en utilisant des analogies

Résumé Méthode

Pensez George W Bush. Il dit à ses soldats: « Va combattre en Irak ». Et c'est tout. Tout ce qu'il a spécifié est qu'il faut faire des combats. Il ne précise pas comment exactement cela se produira. Mais je veux dire, vous ne pouvez pas sortir et « combattre »: qu'est-ce que cela signifie exactement? que je bats avec un B-52 ou mon Derringer? Ces détails spécifiques sont laissés à quelqu'un d'autre. Ceci est une méthode abstraite.

Méthode virtuelle

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

  1. Trouver l'ennemi
  2. Neutraliser lui.
  3. Avoir une bière après

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

Bloggs privé Job lit l'ordre de Petraeus et reçoit l'autorisation de mettre en œuvre sa propre version de combat, selon ses exigences particulières:

  1. Trouvez ennemi.
  2. lui tirer une balle dans la tête.
  3. Go
  4. Avoir la bière.

Nouri al Maliki reçoit également les mêmes ordres de Petraeus. Il est de combattre aussi. Mais il est un homme politique, pas un homme d'infanterie. il ne peut évidemment pas faire le tour de tir ses ennemis Politican dans la tête. Parce que Petraeus lui a donné une méthode virtuelle, puis Maliki peut mettre en œuvre sa propre version de la méthode de lutte, selon ses circonstances particulières:

  1. Trouvez ennemi.
  2. l'ont arrêté avec une BS forgées de toutes pièces charges.
  3. Go
  4. Avoir la bière.

En d'autres termes, une méthode virtuelle fournit des instructions boilerplate -. Mais ce sont des instructions générales, qui peuvent être rendues plus spécifiques par des personnes 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 ne prouve pas les détails de mise en œuvre. Cela doit être fourni par quelqu'un d'autre. Ceci est une méthode abstraite.

  • Petraeus d'autre part Finalité 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.

espoir qui aide.

Fonction Abstract (méthode):

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

● Il ne dispose pas de corps.

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

● Si une méthode est abstraite alors la classe devrait faire abstraction.

fonction virtuelle (méthode):

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

● Il appartient à la classe dérivée il faut passer outre ou non.

La réponse a été fourni un certain nombre de fois, mais la question quand utiliser chacun une décision en temps de conception. Je le voir comme une bonne pratique pour essayer de regrouper les définitions de méthodes communes en interfaces distinctes et les tirer dans des classes à des niveaux d'abstraction appropriés. Dumping un ensemble commun de définitions de méthodes abstraites et virtuelles dans une classe rend la unistantiable de classe 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 à vos applications besoins spécifiques.

De l'objet général vue orientée:

En ce qui concerne la méthode abstraite : Lorsque vous mettez une méthode abstraite dans la classe parente réellement votre disent aux classes d'enfants: Hey noter que vous avez une signature de méthode comme celui-ci. Et si vous voulez l'utiliser, vous devez mettre en œuvre votre propre!

En ce qui concerne la fonction virtuelle : Lorsque vous mettez une méthode virtuelle dans la classe parent, vous dites aux classes dérivées: Hey il y a une fonctionnalité ici que faire quelque chose pour vous. Si cela est utile pour vous venez de l'utiliser. Dans le cas contraire, annuler et mettre en œuvre votre code, vous pouvez même utiliser ma mise en œuvre dans votre code!

c'est une philosophie à propos de différence entre ce concept deux en général OO

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

Pour les fonctions

  1. fonction abstraite ont seulement la seule signature, la classe d'entraînement devrait passer outre la fonctionnalité.
  2. fonction virtuelle contiendra la partie de la fonctionnalité de la classe d'entraînement peut ou ne peut pas la remplacer selon l'exigence

Vous pouvez décider avec votre exigence.

méthode abstraite ne marche pas avoir un implementation.It est déclaré dans la classe parente. La classe des enfants est resposible pour la mise en œuvre de cette méthode.

La méthode virtuelle devrait avoir une mise en œuvre dans la classe mère et il facilite la classe des enfants de faire le choix d'utiliser ou non que la mise en œuvre de la classe mère ou d'avoir une nouvelle mise en œuvre pour lui-même pour cette méthode dans la classe des enfants.

Une fonction abstraite est « juste » une signature, sans mise en œuvre. Il est utilisé dans une interface de déclarer comment la classe peut être utilisée. Il doit être mis en œuvre dans l'une des classes dérivées.

fonction virtuelle (méthode en fait), est une fonction vous déclarez ainsi, et devrait mis en œuvre dans l'une des classes de hiérarchie d'héritage.

Les instances héritées de cette classe, hériteront la mise en œuvre et, à moins que vous le mettre en œuvre, dans une classe de niveau hiérarchique inférieur.

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

Une fonction abstraite ou la méthode est un « nom de l'opération » public exposée par une classe, son but, ainsi que des classes abstraites, est de fournir principalement une forme de contrainte dans la conception des objets contre la structure qu'un objet doivent mettre en œuvre.

En fait, les classes qui héritent de sa classe abstraite doivent donner une mise en œuvre à cette méthode, les compilateurs généralement provoquer une erreur quand ils ne le font pas.

Utilisation des classes et méthodes abstraites est important surtout pour éviter que, en se concentrant sur les détails de mise en œuvre lors de la conception des classes, la structure classes trop liée aux mises en œuvre, créant ainsi des dépendances et le couplage entre les classes qui collaborent entre eux.

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

Ils représentent tous deux une forme de polymorpfhism en paradigme de l'orientation de l'objet.

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

Nous concevons une bonne structure abstraite des objets principaux de notre solution, puis créer des implémentations de base en localisant les plus sujettes à des spécialisations supplémentaires et nous faisons ceux-ci comme virtuals, enfin nous sommes spécialisés nos implémentations de base, eventyually « dominante » virtuels hérités .

Ici, je suis en train d'écrire quelques exemples de code espérant que ce peut être un exemple assez concret pour voir les comportements des interfaces, classes abstraites et les classes ordinaires à un niveau très basique. Vous pouvez également trouver ce code dans github comme un projet si vous voulez l'utiliser comme une démonstration: 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(){
    //
    //    }
    }
}

Pour ma compréhension:

Résumé Méthodes:

Seule la classe abstraite peut contenir des méthodes abstraites. Aussi la classe dérivée doivent mettre en œuvre la méthode et aucune mise en œuvre est prévue dans la classe.

Méthodes virtuelles:

Une classe peut déclarer ces et aussi assurer la mise en œuvre du même. Aussi la classe dérivée doivent mettre en œuvre de la méthode pour la remplacer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top