¿Cuál es la diferencia entre una función abstracta y una función virtual? ¿En qué casos se recomienda usar virtual o abstracto? ¿Cuál es el mejor enfoque?
oop
programming-languages
abstract
virtual-functions
Moran Helman
fuente
fuente
Respuestas:
Una función abstracta no puede tener funcionalidad. Básicamente estás diciendo que cualquier clase secundaria DEBE dar su propia versión de este método, sin embargo, es demasiado general incluso para tratar de implementarla en la clase principal.
Una función virtual , básicamente es mirar, aquí está la funcionalidad que puede o no ser lo suficientemente buena para la clase secundaria. Entonces, si es lo suficientemente bueno, use este método, si no, luego anúleme y proporcione su propia funcionalidad.
fuente
Una función abstracta no tiene implementación y solo puede declararse 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:
fuente
MyBase
clase no tiene que implementar la clase abstracta , de alguna manera? No hago esto a menudo, por lo que podría estar equivocado. No veo eso en tu ejemplo.abstract
clases pueden tenerabstract
miembros.abstract
clase que hereda de unaabstract
clase imprescindibleoverride
suabstract
miembros.abstract
miembro es implícitamentevirtual
.abstract
miembro no puede proporcionar ninguna implementación (abstract
se llamapure virtual
en algunos idiomas).fuente
virtual
o novirtual
. Unabstract
miembro (es decir, propiedad abstracta, método abstracto) es como un método virtual, es decir, puede anularlo, excepto que no lleva consigo una implementación predeterminada.Siempre debe anular una función abstracta.
Así:
fuente
Función abstracta:
Función virtual:
fuente
Método abstracto: cuando una clase contiene un método abstracto, esa clase debe declararse 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 una lógica adicional, o reemplazar la lógica con su propia implementación.
Cuándo usar qué: en algunos casos, 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 ese caso, pero sabe que los implementadores de esa interfaz también tendrán otro método común (para el cual 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.
fuente
explicación: con analogías espero que 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 quema un rascacielos. Pero afortunadamente tenemos un manual de instrucciones en algún lugar aquí sobre qué hacer en caso de incendio:
Salida de incendios()
Esto 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 posibilidades de que la salida de incendios esté bloqueada o dañada, en cuyo caso está completamente atornillado y se tostará a menos que tome alguna acción drástica. Con los métodos virtuales puede hacer exactamente eso: puede anular el plan básico FireEscape () con su propia versión del plan:
En otras palabras, los métodos virtuales proporcionan un plan básico, que puede ser anulado 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 capacitadas. 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 se ve obligada a desarrollar su propio método FireEscape (). Un chico saldrá por la escalera de incendios. Otro tipo se lanzará en paracaídas. Otro tipo usará la tecnología de propulsión de cohetes para volar lejos del edificio. Otro chico hará rappel. A la gerencia no le importa cómo se escapa, siempre que tenga un plan básico FireEscape (); si no lo hacen, puede estar seguro de que 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 otra vez?
Método abstracto: las subclases se ven 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?
fuente
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 utilizando la anulación, reemplazando el comportamiento en la superclase. Si no anula, obtiene el comportamiento original. Si lo haces, siempre obtienes el nuevo comportamiento. Esto se opone a los métodos no virtuales, que no pueden anularse pero pueden ocultar el método original. Esto se hace usando el
new
modificador.Vea el siguiente ejemplo:
Cuando hago una instancia
DerivedClass
y llamoSayHello
, oSayGoodbye
recibo "Hola" y "Hasta luego". Si llamoHelloGoodbye
, recibo "Hola" y "Hasta luego". Esto se debe a queSayGoodbye
es virtual y se puede reemplazar por clases derivadas.SayHello
solo está oculto, así que cuando llamo a eso 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.
fuente
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.
fuente
Lo simplifiqué haciendo algunas mejoras en las siguientes clases (de otras respuestas):
fuente
La vinculación es el proceso de asignar un nombre a una unidad de código.
El enlace tardío 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 considere:
Entonces, la respuesta corta es:
virtual
es una instrucción de enlace tardío para la máquina (tiempo de ejecución) mientras queabstract
es una instrucción de enlace tardío para el humano (programador)En otras palabras,
virtual
significa:"Estimado tiempo de ejecución , vincule el código apropiado a este nombre haciendo lo que mejor sabe hacer: buscar "
Mientras que
abstract
significa:"Estimado programador , enlace el código apropiado a este nombre haciendo lo que mejor sabe hacer: inventar "
En aras de la integridad, la sobrecarga significa:
"Estimado compilador , vincula el código apropiado a este nombre haciendo lo que mejor sabes hacer: ordenar ".
fuente
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)
fuente
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.
función en la clase secundaria (que se puede decir como un concepto de
sombreado).
Método abstracto
Resumen significa que DEBEMOS anularlo.
Una función abstracta no tiene implementación y debe estar en una clase abstracta.
Solo se puede declarar. Esto obliga a la clase derivada a proporcionar la implementación de la misma.
Un miembro abstracto es implícitamente virtual. El resumen puede llamarse como virtual puro en algunos de los idiomas.
fuente
He visto en algunos lugares que el método abstracto se define a continuación. ** **
** Sentí que es así.
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) No se puede implementar un método abstracto en la misma clase abstracta.
Diría que ... si estamos implementando una clase abstracta, debe 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 implementar un método virtual en una clase heredada.
fuente
La mayoría de los ejemplos anteriores usan código, y son muy, 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 códigos / términos 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 pelear en Irak". Y eso es. Todo lo que ha especificado es que la lucha debe hacerse. No especifica cómo exactamente sucederá eso. Pero quiero decir, no puedes simplemente salir y "pelear": ¿qué significa eso exactamente? Cómo 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 está en lo alto del ejército. Él ha definido lo que significa pelear:
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 maniobra y alcance: ha permitido que otros cambien su definición de "lucha", de acuerdo con sus requisitos particulares.
Private Job Bloggs lee la orden de Petraeus y se le da permiso para implementar su propia versión de lucha, de acuerdo con sus requisitos particulares:
Nouri al Maliki también recibe las mismas órdenes de Petraeus. Él es para pelear 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:
En otras palabras, un método virtual proporciona instrucciones repetitivas, 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 a sus subordinados para anular sus órdenes con su propia versión, si pueden llegar a algo mejor.
Espero que ayude.
fuente
Función abstracta (método):
● Un método abstracto es un método que se declara con la palabra clave abstract.
● No tiene cuerpo.
● Debe ser implementado por la clase derivada.
● Si un método es abstracto, la clase debería abstraer.
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 clase derivado usando la palabra clave override.
● Depende de la clase derivada si se debe anular o no.
fuente
La respuesta se ha proporcionado varias veces, pero la pregunta sobre cuándo usar cada una es una decisión en tiempo de diseño. Consideraría una buena práctica intentar agrupar definiciones de métodos comunes en interfaces distintas y agruparlas en clases en los niveles de abstracción apropiados. Volcar un conjunto común de definiciones de métodos abstractos y virtuales en una clase hace que la clase no se pueda resistir cuando sea 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.
fuente
Función abstracta no puede tener un cuerpo y DEBE ser anulada por las clases secundarias
La función virtual tendrá un cuerpo y puede ser anulada o no por las clases secundarias
fuente
Desde la vista general orientada a objetos: con
respecto al método abstracto : cuando coloca un método abstracto en la clase principal, en realidad está diciendo a las clases secundarias: Oye, tenga en cuenta que tiene una firma de método como esta. Y si quieres usarlo, ¡debes implementar el tuyo!
Con respecto a la función virtual : cuando coloca un método virtual en la clase principal, le dice a las clases derivadas: Hola, aquí hay una funcionalidad que hace algo por usted. Si esto es útil para usted, simplemente úselo. Si no, anule esto e implemente su código, ¡incluso puede usar mi implementación en su código!
Esta es una filosofía sobre la diferencia entre estos dos conceptos en General OO
fuente
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 implementarse en una de las clases derivadas.
La función virtual (método en realidad), es una función que usted 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.
fuente
Si una clase deriva de esta clase abstracta, se ve obligada a anular el miembro abstracto. Esto es diferente del modificador virtual, que especifica que el miembro puede ser anulado opcionalmente.
fuente
No hay nada llamado clase virtual en C #.
Para funciones
Puedes decidir con tu requerimiento.
fuente
El método abstracto no tiene una implementación. Se declara en la clase padre. La clase secundaria 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 elija si usar esa implementación de la clase principal o tener una nueva implementación para sí mismo para ese método en la clase secundaria.
fuente
Desde un fondo de C ++, C # virtual corresponde a C ++ virtual, mientras que los métodos abstractos de C # corresponden a la función virtual pura de C ++
fuente
Una función o método abstracto es un "nombre de operación" 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 implementar.
De hecho, las clases que heredan de su clase abstracta tienen que dar una implementación a este método, generalmente los compiladores generan errores cuando no lo hacen.
El uso de clases y métodos abstractos es importante principalmente para evitar que al centrarse en los detalles de implementación al diseñar las clases, la estructura de las clases esté demasiado relacionada con las implementaciones, por lo que se crean dependencias y se acoplan las clases que colaboran entre ellas.
Una función o método virtual es simplemente un método que modela el comportamiento público de una clase, pero que podemos dejar libre para modificarlo en la cadena de herencia, porque creemos que las clases secundarias podrían necesitar implementar algunas extensiones específicas para ese comportamiento.
Ambos representan una forma de polimorfismo en el paradigma de orientación a objetos.
Podemos usar métodos abstractos y funciones virtuales juntos para soportar un buen modelo de herencia.
Diseñamos una buena estructura abstracta de los objetos principales de nuestra solución, luego creamos implementaciones básicas localizando aquellas más propensas a futuras especializaciones y las hacemos como virtuales, finalmente especializamos nuestras implementaciones básicas, eventualmente "anulando" las virtuales heredadas.
fuente
Aquí estoy escribiendo un código de muestra con la esperanza de que este sea un ejemplo bastante tangible para ver los comportamientos de las interfaces, clases abstractas y clases ordinarias en un nivel muy básico. También puede encontrar este código en github como proyecto si desea usarlo como demostración: https://github.com/usavas/JavaAbstractAndInterfaceDemo
fuente
A mi entender:
Métodos abstractos:
Solo la clase abstracta puede contener métodos abstractos. Además, 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. Además, la clase derivada debe implementar el método para anularlo.
fuente