method implementar c# oop programming-languages abstract virtual-functions

c# - implementar - ¿Cuál es la diferencia entre una función abstracta y una función virtual?



virtual class c# (24)

  1. Sólo las 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 abstract es implícitamente virtual .
  4. Un miembro abstract no puede proporcionar ninguna implementación (el abstract se denomina pure virtual en algunos idiomas).

¿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 enfoque más correcto?


A mi entender:

Métodos abstractos:

Sólo la clase abstracta puede contener métodos abstractos. También la clase derivada necesita implementar el método y no se proporciona ninguna implementación en la clase.

Métodos virtuales:

Una clase puede declararlos y también proporcionar la implementación de los mismos. También la clase derivada necesita implementar el método para anularlo.


Básicamente, utiliza un método virtual cuando desea que los herederos amplíen la funcionalidad SI lo desean.

Utiliza métodos abstractos cuando desea que los herederos implementen la funcionalidad (y en este caso no tienen otra opción)


Desde la vista general orientada a objetos:

Con respecto al método abstracto : cuando pones un método abstracto en la clase principal, en realidad estás diciendo a las clases secundarias: Oye, ten en cuenta que tienes una firma de método como esta. Y si quieres usarlo debes implementar el tuyo!

Respecto a la función virtual : cuando pones un método virtual en la clase principal, le estás diciendo a las clases derivadas: Oye, aquí hay una funcionalidad que hace algo por ti. Si esto es útil para ti solo úsalo. Si no, anule esto e implemente su código, ¡incluso usted puede usar mi implementación en su código!

Esta es una filosofía diferente acerca de este concepto en General OO.


Desde un fondo de C ++, C # virtual corresponde a C ++ virtual, mientras que los métodos abstractos de C # corresponden a C ++ función virtual pura


El método abstracto no tiene una implementación. Se declara en la clase padre. La clase infantil es responsable de implementar ese método.

El método virtual debe tener una implementación en la clase principal y facilita que la clase secundaria tome la decisión de usar esa implementación de la clase principal o tener una nueva implementación para ese método en la clase secundaria.


Explicación: con analogías. ojala te ayude

Contexto

Trabajo en el piso 21 de un edificio. Y estoy paranoico sobre el fuego. De vez en cuando, en algún lugar del mundo, un fuego está quemando un rascacielos. Pero, afortunadamente, tenemos un manual de instrucciones en algún lugar sobre qué hacer en caso de incendio:

Salida de incendios()

  1. No recoja pertenencias
  2. Caminar a la salida de incendios
  3. Salir del edificio

Este es básicamente un método virtual llamado FireEscape ()

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 probabilidad de que la salida de incendios esté bloqueada o dañada, en cuyo caso está completamente atornillado y se convertirá en una tostada a menos que tome una acción drástica. Con los métodos virtuales puede hacer exactamente eso: puede anular el plan básico de FireEscape () con su propia versión del plan:

  1. Correr a la ventana
  2. Saltar por la ventana
  3. Paracaídas con seguridad hasta el fondo.

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

Métodos abstractos

No todas las organizaciones están bien perforadas. Algunas organizaciones no hacen simulacros de incendio. No tienen una política general de escape. Cada hombre es para sí mismo. La gerencia solo está interesada en tal política existente.

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

¿Cuál es la diferencia entre los dos de nuevo?

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

Ahora que no fue tan difícil ¿verdad?


Función abstracta (método):

● Un método abstracto es un método que se declara con la palabra clave resumen.

● No tiene cuerpo.

● Debe ser implementado por la clase derivada.

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

función virtual (método):

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

● Depende de la clase derivada si lo reemplaza o no.


Función abstracta:

  1. Solo se puede declarar dentro de clase abstracta.
  2. Solo contiene la declaración del método, no la implementación en la clase abstracta.
  3. Debe ser anulado en la clase derivada.

Función virtual:

  1. Se puede declarar dentro de clase abstracta y no abstracta.
  2. Contiene la implementación del método.
  3. Puede ser anulado.

He visto en algunos lugares que el método abstracto se define a continuación. **

"Un método abstracto debe tener que implementarse en la clase infantil"

** Sentí que es como

No es necesario que se implemente un método abstracto en una clase secundaria, si la clase secundaria también es abstracta .

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

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

No es necesario que un método virtual se implemente 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(); } }


Hice esto más simple haciendo algunas mejoras en las siguientes clases (de 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"); } } }


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

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

Método abstracto

Piensa en George W. Bush. Él le dice a sus soldados: "Ve a luchar en Irak". Y eso es. Todo lo que ha especificado es que hay que luchar. Él no especifica cómo exactamente eso sucederá. Pero quiero decir, no puedes salir y "luchar": ¿qué significa eso exactamente? ¿Peleo 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. Ha definido lo que significa la lucha:

  1. Encontrar al enemigo
  2. Neutralizarlo.
  3. Tomar una cerveza despues

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ífico. Lo bueno para Petraeus es que sus órdenes tienen margen de acción y alcance: ha permitido a otros cambiar su definición de "lucha", de acuerdo con sus requisitos particulares.

Private Job Bloggs lee la orden de Petraeus y recibe permiso para implementar su propia versión de la pelea, de acuerdo con sus requisitos particulares:

  1. Encontrar enemigo
  2. Dispararle en la cabeza
  3. Vete a casa
  4. Tomar una 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 hombre de infantería. Obviamente, no puede andar disparando a sus enemigos políticos en la cabeza. Debido a que Petraeus le ha dado un método virtual, Maliki puede implementar su propia versión del método de lucha, de acuerdo con sus circunstancias particulares:

  1. Encontrar enemigo
  2. Haz que lo arresten con algunos BS inventaron cargos.
  3. Vete a casa
  4. Tomar una cerveza

En otras palabras, un método virtual proporciona instrucciones repetidas, pero estas son instrucciones generales, que pueden ser más específicas para las personas de la jerarquía del ejército, de acuerdo con sus circunstancias particulares.

La diferencia entre los dos

  • George Bush no prueba ningún detalle de implementación. Esto debe ser proporcionado por otra persona. Este es un método abstracto.

  • Petraeus, por otro lado , proporciona detalles de implementación, pero ha dado permiso para que sus subordinados anulen sus órdenes con su propia versión, si pueden encontrar algo mejor.

Espero que ayude.


La respuesta se ha proporcionado varias veces, pero la pregunta sobre cuándo usar cada una es una decisión de tiempo de diseño. Me parece una buena práctica tratar de agrupar definiciones de métodos comunes en interfaces distintas y agruparlas en clases en los niveles de abstracción apropiados. Al incluir un conjunto común de definiciones de métodos abstractos y virtuales en una clase, la clase no se puede certificar cuando es mejor definir una clase no abstracta que implemente un conjunto de interfaces concisas. Como siempre, depende de lo que mejor se adapte a las necesidades específicas de sus aplicaciones.


Los métodos abstractos son siempre virtuales. No pueden tener una implementación.

Esa es la principal diferencia.

Básicamente, usaría un método virtual si tiene la implementación ''predeterminada'' y desea permitir que los descendientes cambien su comportamiento.

Con un método abstracto, obliga a los descendientes a proporcionar una implementación.


Método abstracto: cuando una clase contiene un método abstracto, esa clase debe ser declarada como abstracta. El método abstracto no tiene implementación y, por lo tanto, las clases que se derivan de esa clase abstracta, deben proporcionar una implementación para este método abstracto.

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

Cuándo usar qué: en algunos casos, usted sabe que ciertos tipos deberían tener un método específico, pero no sabe qué implementación debería tener este método.
En tales casos, puede crear una interfaz que contenga un método con esta firma. Sin embargo, si tiene tal caso, pero sabe que los implementadores de esa interfaz también tendrán otro método común (para el que ya puede proporcionar la implementación), puede crear una clase abstracta. Esta clase abstracta contiene el método abstracto (que debe ser anulado) y otro método que contiene la lógica "común".

Se debe usar un método virtual si tiene una clase que se puede usar directamente, pero para la cual desea que los herederos puedan cambiar cierto comportamiento, aunque no es obligatorio.


No hay nada llamado clase virtual en C #.

Para funciones

  1. La función de resumen solo tiene firma, la clase de unidad debe sobrescribir con la funcionalidad.
  2. La función virtual mantendrá la parte de la funcionalidad que la clase de unidad puede o no puede anular según el requisito

Usted puede decidir con su requerimiento.


Siempre debes anular una función abstracta.

Así:

  • Funciones abstractas : cuando el heredero debe proporcionar su propia implementación
  • Virtual - cuando le corresponde al heredero decidir

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 cualquier clase con un método abstracto debe ser una clase abstracta) y debe implementarse en una clase concreta.

Un método virtual es un método que se puede anular en una clase derivada usando la anulación, reemplazando el comportamiento en la superclase. Si no anulas, obtienes el comportamiento original. Si lo haces, siempre obtendrás el nuevo comportamiento. Esto opuesto a los métodos no virtuales, que no pueden ser anulados pero pueden ocultar el método original. Esto se hace usando el new modificador.

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 hago una instancia de DerivedClass y llamo a SayHello , o SayGoodbye , recibo "Hola" y "Hasta luego". Si llamo a HelloGoodbye , recibo "Hello" y "Nos vemos luego". Esto se debe a que SayGoodbye es virtual y puede ser reemplazado por clases derivadas. SayHello solo está oculto, así que cuando lo llamo desde mi clase base obtengo mi método original.

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


Una función abstracta es "solo" una firma, sin una implementación. Se usa en una interfaz para declarar cómo se puede usar la clase. Debe ser implementado en una de las clases derivadas.

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

Las instancias heredadas de dicha clase también heredan la implementación, a menos que la implemente, en una clase de jerarquía inferior.


Una función abstracta no tiene implementación y solo se puede declarar en una clase abstracta. Esto obliga a la clase derivada a proporcionar una implementación. Una función virtual proporciona una implementación predeterminada y puede existir en una clase abstracta o en 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(); }


La función abstracta no puede tener un cuerpo y DEBE ser anulada por clases de niños

La función virtual tendrá un cuerpo y puede o no ser anulada por clases secundarias


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

La vinculación tardía significa que usamos el nombre, pero diferimos el mapeo. En otras palabras, primero creamos / mencionamos el nombre y dejamos que algún proceso posterior maneje la asignación de código a ese nombre.

Ahora considera:

  • En comparación con los humanos, las máquinas son muy buenas para buscar y clasificar
  • En comparación con las máquinas, los humanos son realmente buenos en invención e innovación.

Entonces, la respuesta corta es: virtual es una instrucción de enlace tardío para la máquina (tiempo de ejecución), mientras que abstract es la instrucción de enlace tardío para el humano (programador)

En otras palabras, virtual medios virtual :

"Estimado tiempo de ejecución , vincule el código apropiado a este nombre haciendo lo que mejor hace: buscar "

Mientras que los medios abstract :

"Estimado programador , vincule el código apropiado a este nombre haciendo lo que mejor hace: inventar "

En aras de la integridad, la sobrecarga significa:

“Estimado compilador , enlace el código apropiado a este nombre haciendo lo que mejor haces: ordenar ”.


Método virtual :

  • Virtual significa que podemos anularlo.

  • La función virtual tiene una implementación. Cuando heredamos la clase, podemos anular la función virtual y proporcionar nuestra propia lógica.

  • Podemos cambiar el tipo de retorno de la función virtual al implementar el
    función en la clase infantil (que se puede decir como un concepto de
    Sombreado).

Método abstracto

  • El resumen significa que DEBEMOS anularlo.

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

  • Solo puede ser declarado. Esto obliga a la clase derivada a proporcionar la implementación de la misma.

  • Un miembro abstracto es implícitamente virtual. El resumen se puede llamar como virtual puro en algunos de los idiomas.

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


Una función abstracta no puede tener funcionalidad. Básicamente, está diciendo que cualquier clase secundaria DEBE dar su propia versión de este método, sin embargo, es demasiado general como para intentar implementarla en la clase principal.

Una función virtual , básicamente dice look, aquí está la funcionalidad que puede o no ser lo suficientemente buena para la clase infantil. Entonces, si es lo suficientemente bueno, usa este método, si no, entonces anulame y proporciona tu propia funcionalidad.