Pregunta

¿Cuál es la diferencia entre una función abstracta y una función virtual?¿En qué casos se recomienda utilizar virtual o abstracto?¿Cuál es el mejor enfoque?

¿Fue útil?

Solución

Una función resumen no puede tener funcionalidad. Básicamente, se está diciendo, cualquier clase hija tiene que dar su propia versión de este método, sin embargo, es demasiado general incluso a tratar de poner en práctica en la clase padre.

Una función virtual , está diciendo básicamente vistazo, aquí está la funcionalidad que pueden o no ser lo suficientemente bueno para la clase hija. Así que si es lo suficientemente bueno, utilice este método, si no, entonces me anular, y proporcionar su propia funcionalidad.

Otros consejos

Una función abstracta no tiene APLICACIÓN Y sólo puede ser declarada en una clase abstracta. Esto obliga a la clase derivada para proporcionar una implementación.

Una función virtual proporciona una implementación por defecto y puede existir en cualquiera de una clase abstracta o una clase no abstracta.

Así, por ejemplo:

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. Sólo clases abstract pueden tener miembros abstract.
  2. Una clase no abstract que hereda de una clase abstract debe override sus miembros abstract.
  3. Un miembro de abstract está implícitamente virtual.
  4. Un miembro de abstract no puede proporcionar ninguna aplicación (abstract se llama pure virtual en algunos idiomas).

Siempre se debe anular una función abstracta.

Así:

  • Extracto funciones - cuando la heredera deben proporcionar su propia implementación
  • virtual - cuando corresponde a la heredera de decidir

Extracto Función:

  1. Se puede declarar sólo dentro de la clase abstracta.
  2. Sólo contiene No declaración de método la puesta en práctica en la clase abstracta.
  3. Debe ser anulado en la clase derivada.

Función virtual:

  1. Se puede declarar en el interior abstracto, así como clase no abstracta.
  2. Contiene implementación del método.
  3. Puede ser anulado.

método Resumen: Cuando una clase contiene un método abstracto, que clase debe ser declarado como abstracto. El método abstracto no tiene ninguna aplicación y por lo tanto, las clases que se derivan de esa clase abstracta, debe proporcionar una implementación de este método abstracto.

método Virtual: Una clase puede tener un método virtual. El método virtual tiene una implementación. Cuando se hereda de una clase que tiene un método virtual, puede reemplazar el método virtual y proporcionar lógica adicional, o reemplazar la lógica con su propia aplicación.

Cuando usar lo que: En algunos casos, usted sabe que ciertos tipos deben tener un método específico, pero, usted no sabe lo que la aplicación de este método debe tener.
En tales casos, puede crear una interfaz que contiene un método con esta firma. Sin embargo, si usted tiene un caso, pero ya se sabe que los ejecutores de esa interfaz también tendrán otro método común (para lo cual ya se puede proporcionar a la aplicación), se puede crear una clase abstracta. Esta clase abstracta contiene entonces el método abstracto (que debe ser anulado), y otro método que contiene la lógica de 'común'.

Un método virtual debe utilizarse si usted tiene una clase que puede ser utilizado directamente, pero para el que desea herederos sean capaces de cambiar ciertos comportamientos, aunque no es obligatorio.

explicación:con analogías.ojalá te ayude.

Contexto

Trabajo en el piso 21 de un edificio.Y estoy paranoico con el fuego.De vez en cuando, en algún lugar del mundo, un incendio devora un rascacielos.Pero por suerte tenemos por aquí un manual de instrucciones sobre qué hacer en caso de incendio:

Salida de incendios()

  1. No recojas pertenencias
  2. Caminar hasta la escalera de incendios
  3. Salir del edificio

Este es básicamente un método virtual llamado Salida de incendios()

Método virtual

Este plan es bastante bueno para el 99% de las circunstancias.Es un plan básico que funciona.Pero hay un 1% de posibilidades de que la escalera de incendios esté bloqueada o dañada, en cuyo caso estás completamente jodido y te convertirás en un tostado a menos que tomes alguna medida drástica.Con los métodos virtuales puedes hacer precisamente eso:puedes anular el plan básico de FireEscape() con tu propia versión del plan:

  1. correr a la ventana
  2. Saltar por la ventana
  3. Lánzate en paracaídas de forma segura hasta el fondo

En otras palabras Los métodos virtuales proporcionan un plan básico, que puede anularse si es necesario..Las subclases pueden anular el método virtual de la clase principal si el programador lo considera apropiado.

Métodos abstractos

No todas las organizaciones están bien preparadas.Algunas organizaciones no realizan simulacros de incendio.No tienen una política general de escape.Cada hombre es para sí mismo.La dirección sólo está interesada en que exista una política de este tipo.

En otras palabras, cada persona es forzado para desarrollar su propio método FireEscape().Un tipo saldrá por la escalera de incendios.Otro chico se lanzará en paracaídas.Otro tipo utilizará tecnología de propulsión de cohetes para volar lejos del edificio.Otro chico descenderá en rápel.A la gerencia no le importa cómo usted escapa, siempre y cuando tenga un plan básico de FireEscape(); si no lo tiene, puede estar seguro de que OHS caerá sobre la organización como una tonelada de ladrillos.Esto es lo que se entiende por método abstracto.

¿Cuál es la diferencia entre los dos nuevamente?

Método abstracto:las subclases son forzado para implementar su propio método FireEscape.Con un método virtual tienes un plan básico esperándote, pero puedes elegir para implementar el tuyo propio si no es lo suficientemente bueno.

Eso no fue tan difícil ¿verdad?

Un método abstracto es un método que debe implementarse para hacer una clase concreta. La declaración está en la clase abstracta (y de cualquier clase con un método abstracto debe ser una clase abstracta) y debe ser implementado en una clase concreta.

Un método virtual es un método que se puede sustituir en una clase derivada usando la anulación, reemplazando el comportamiento en la superclase. Si no se sobreescribe, se obtiene el comportamiento original. Si lo hace, siempre obtendrá el nuevo comportamiento. Esta contraposición a los métodos no virtuales, que no se pueden reemplazar, pero pueden ocultar el método original. Esto se hace usando el modificador new.

Vea el siguiente ejemplo:

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

Cuando instanciar DerivedClass y SayHello llamada o SayGoodbye, consigo "Hola allí" y "Nos vemos más tarde". Si llamo HelloGoodbye, consigo "Hola" y "Nos vemos más tarde". Esto se debe a SayGoodbye es virtual, y puede ser sustituido por clases derivadas. SayHello sólo se oculta, por lo que cuando llamo a eso de mi clase base consigo mi método original.

Los métodos abstractos son implícitamente virtual. Definen el comportamiento que debe estar presente, más como una interfaz lo hace.

Los métodos abstractos son siempre virtual. No pueden tener una aplicación.

Esa es la principal diferencia.

Básicamente, se utiliza un método virtual, si usted tiene la aplicación 'por defecto' de la misma y desea permitir que los descendientes para cambiar su comportamiento.

Con un método abstracto, se fuerza descendientes para proporcionar una implementación.

Hice este sencillo al hacer algunas mejoras en las siguientes clases (desde otras respuestas):

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

Encuadernación es el proceso de asignar un nombre a una unidad de código.

Enlace tardío significa que usamos el nombre, pero diferir el mapeo. En otras palabras, creamos / mencionar el nombre primero, y dejar algún proceso posterior manejar la asignación de código para ese nombre.

Ahora considere:

  • En comparación con los seres humanos, las máquinas son muy buenos en búsqueda y clasificación
  • En comparación con las máquinas, los seres humanos son muy buenos en la invención e innovación

Por lo tanto, la respuesta corta es: virtual es una instrucción de enlace en tiempo de la máquina (tiempo de ejecución), mientras que abstract es la instrucción enlace en tiempo para el ser humano (programador)

En otras palabras, virtual significa:

“Estimado tiempo de ejecución , se unen el código correspondiente a este nombre, haciendo lo que mejor sabe hacer: buscar

Mientras que significa abstract:

“Estimado programador , por favor enlazar el código correspondiente a este nombre, haciendo lo que mejor sabe hacer: inventar

En aras de la exhaustividad, sobrecarga significa:

“Estimado compilador , se unen el código correspondiente a este nombre, haciendo lo que mejor sabe hacer: clasificación ”.

Es, básicamente, utiliza un método virtual cuando se desea que los herederos para ampliar la funcionalidad si quieren.

Se utilizan los métodos abstractos cuando se desea que los herederos para implementar la funcionalidad (y en este caso no tienen otra opción)

he visto en algunos lugares el método abstracto se define de la siguiente manera. **

  

"un método abstracto debe tener para implementar en la clase de niño"

** Sentí que es.

No es necesario que un método abstracto tiene que ser implementado en una clase de niños, si la clase hijo también es abstracto ..

1) Un método abstracto no puede es un método privado. 2) un método abstracto no puede ser implementado en la misma clase abstracta.

Yo diría ..si estamos implementando una clase abstracta, que debe tener para anular los métodos abstractos de la clase base abstracta. Debido .. La implantación del método abstracto es con anulación palabra clave .Similar con el método virtual.

No es necesario para un método virtual para ser implementado en una clase heredada.

                                 ----------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étodo virtual :

  • medios virtuales que pueden anular la misma.

  • Función virtual tiene una implementación. Cuando heredamos la que la clase puede reemplazar la función virtual y ofrecer nuestra propia lógica.

  • Podemos cambiar el tipo de retorno de la función virtual, mientras que la aplicación de la
    función en la clase hija (que se puede decir como un concepto de
    Shadowing).

Extracto Método

  • Extracto significa que debemos anularla.

  • Una función abstracta no tiene ninguna aplicación y debe estar en una clase abstracta.

  • Sólo puede ser declarada. Esto obliga a la clase derivada para proporcionar la implementación de la misma.

  • Un miembro de resumen es implícitamente virtual. El resumen puede ser llamado como pura virtual en algunos de los idiomas.

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

Función Extracto no puede tener un cuerpo y deben ser anulados por las clases hijas

Función virtual tendrá un cuerpo y puede o no puede ser anulado por las clases hijas

La mayoría de los ejemplos anteriores use el código - y son muy muy bueno. No necesito añadir a lo que dicen, pero la siguiente es una explicación simple que hace uso de analogías en lugar de código / términos técnicos.

Explicación Simple - Explicación usando analogías

Extracto Método

Piense George W Bush. Dice a sus soldados: "Ir a combatir en Irak". Y eso es. Lo único que ha especificado es que la lucha debe hacerse. No especifica ¿Cómo exactamente que va a pasar. Pero quiero decir, no se puede simplemente salir y "luchar": ¿qué significa eso exactamente? Debo luchar con un B-52 o mi Derringer? Esos detalles específicos se dejan a otra persona. Este es un método abstracto.

Método virtual

David Petraeus es alto en el ejército. Se ha definido lo que significa lucha:

  1. Para el enemigo
  2. neutralizarlo.
  3. Tienen una cerveza después

El problema es que es un método muy general. Es un buen método que funciona, pero a veces no es lo suficientemente específica. Lo bueno de Petraeus es que sus órdenes tienen libertad de acción y alcance -. Le ha permitido a otros a cambiar su definición de "lucha", de acuerdo con sus requisitos particulares

Privada Bloggs Trabajo lee el fin de Petraeus y se le da permiso para poner en práctica su propia versión de la pelea, de acuerdo a sus necesidades particulares:

  1. Encuentra enemigo.
  2. dispararle en la cabeza.
  3. Ir a inicio
  4. Tener cerveza.

Nouri al Maliki también recibe las mismas órdenes de Petraeus. Él es luchar también. Pero él es un político, no un soldado de infantería. Obviamente él no puede ir por ahí disparando sus enemigos Politican en la cabeza. Debido a Petraeus le ha dado un método virtual, a continuación, Maliki puede poner en práctica su propia versión del método de lucha, de acuerdo con sus circunstancias particulares:

  1. Encuentra enemigo.
  2. Haga que lo detuvieron con un poco de BS falsas acusaciones.
  3. Ir a inicio
  4. Tener cerveza.

En otras palabras, un método virtual proporciona instrucciones repetitivo -. Pero estas son las instrucciones generales que se pueden hacer más específica por la gente abajo de la jerarquía del ejército, de acuerdo con sus circunstancias particulares

La diferencia entre los dos

  • George Bush no demuestra ningún detalles de implementación. Esta debe ser proporcionada por alguien más. Este es un método abstracto.

  • Petraeus, por otro lado hace proporcionar detalles de implementación, sino que le ha dado permiso para que sus subordinados para anular sus órdenes con su propia versión, si se puede llegar a algo mejor.

espero que ayude.

función Abstract (método):

● Un método abstracto es un método que se declaró con el resumen de palabras clave.

● No tiene cuerpo.

● Debe ser implementado por la clase derivada.

● Si un método es abstracto entonces la clase debe abstracto.

función virtual (método):

● Un método virtual es el método que se declara con la palabra clave virtual y que puede ser anulado por el método de clase derivada mediante el uso de palabras clave de anulación.

● Depende de la clase derivada si desea reemplazar o no.

La respuesta se ha proporcionado un número de veces, pero el la pregunta sobre cuándo utilizar cada uno es una decisión en tiempo de diseño. Lo vería como una buena práctica para tratar de agrupar definiciones de métodos comunes en las interfaces distintas y tirar de ellos en clases en niveles de abstracción apropiados. Dumping un conjunto común de definiciones abstractas y virtuales método en una clase hace que el unistantiable clase cuando puede ser mejor para definir una clase no abstracta que implementa un conjunto de interfaces concisas. Como siempre, depende de lo que mejor se adapte a sus necesidades específicas aplicaciones.

Desde visión general orientada a objetos:

En cuanto a método abstracto : Cuando se pone un método abstracto en la clase padre realmente su están diciendo a las clases hijas: Hola en cuenta que tiene una firma de método como este. Y si quieres usarlo se debe implementar su propio!

En cuanto a función virtual : Cuando se pone un método virtual en la clase padre que está diciendo a las clases derivadas: Hey hay una funcionalidad aquí que haga algo por ti. Si esto es útil para que sólo lo utilizan. Si no es así, modificar esto y poner en práctica su código, aunque se puede usar mi aplicación en el código!

esto es una filosofía sobre diferentes entre estos dos concepto en general OO

Hay nada llamada clase virtual en C #.

Para las funciones

  1. función de resumen solamente tiene sólo firma, la clase de unidad debe pasar por encima con la funcionalidad.
  2. función virtual llevará a cabo la parte de la funcionalidad de la clase de accionamiento puede o no puede anularlo según el requisito

Puede decidir con su requisito.

Resumen método tampoco tienen un implementation.It se declara en la clase padre. La clase hija es resposible para la aplicación de dicho método.

método virtual debe tener una implementación en la clase padre y facilita la clase hija a tomar la decisión de si usar que la implementación de la clase padre o tener una nueva aplicación por sí mismo para ese método en la clase de niño.

Una función resumen es "sólo" una firma, sin una aplicación. Se utiliza en una interfaz para declarar cómo se puede utilizar la clase. Se debe implementarse en una de las clases derivadas.

Función virtual (método en realidad), es una función que declarar también, y debe implementado en una de las clases jerarquía de herencia.

Los casos heredados de dicha clase, heredan la aplicación, así, a menos que se implemente, en una clase de jerarquía inferior.

A partir de un fondo de C ++, C # corresponde virtuales a C ++ virtual, mientras que los métodos abstractos C # corresponde a la función virtual pura C ++

Una función abstracta o método es "el nombre de la operación" a un público expuesto por una clase, su objetivo, junto con las clases abstractas, es principalmente proporcionar una forma de restricción en el diseño de objetos contra la estructura que un objeto tiene que poner en práctica.

De hecho, las clases que heredan de la clase abstracta tienen que dar una implementación de este método, los compiladores en general, elevar errores cuando no lo hacen.

Uso de clases y métodos abstractos es importante sobre todo para evitar que al centrarse en los detalles de implementación en el diseño de las clases, la estructura de clases sea demasiado relacionado con las implementaciones, por lo que la creación de dependencias y de acoplamiento entre las clases que colaboran entre ellos.

Una función virtual o método es simplemente un método que modela un comportamiento público de una clase, pero que pueden dejar libre de modificar en la cadena de herencia, porque creemos que las clases hijas podrían tener que poner en práctica algunas extensiones específicas para ese comportamiento.

Ambos representan una forma de polymorpfhism en el paradigma orientación a objetos.

Podemos utilizar métodos abstractos y funciones virtuales en conjunto para apoyar un buen modelo de herencia.

Diseñamos una buena estructura abstracta de los objetos principales de nuestra solución, a continuación, crear implementaciones básicas mediante la localización de los más propensos a las nuevas especializaciones y hacemos estos queridos como los virtuales, finalmente, que se especializan nuestras implementaciones básicas, eventyually "superior" heredado los virtuales .

Aquí estoy escribiendo un código de ejemplo la esperanza de que esto puede ser un ejemplo bastante tangible para ver el comportamiento de las interfaces, clases abstractas y clases ordinarias en un nivel muy básico. También se puede encontrar este código en GitHub como un proyecto si desea utilizarlo como una demostración: 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(){
    //
    //    }
    }
}

A mi entender:

Extracto Métodos:

Sólo la clase abstracta puede contener métodos abstractos. También la clase derivada necesidad de aplicar el método y sin aplicación se proporciona en la clase.

métodos virtuales:

Una clase puede declarar éstos y garantizar además la aplicación de la misma. También la clase derivada necesita para poner en práctica del método para anularlo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top