¿Cuáles son las diferencias entre declarar un método en un tipo base " virtual
" y luego anularlo en un tipo secundario usando la override
palabra clave " " en lugar de simplemente usar la new
palabra clave " " al declarar el método coincidente en el tipo secundario?
c#
syntax
overriding
method-hiding
member-hiding
i3ensays
fuente
fuente
new
crea un nuevo miembro con el mismo nombre y hace que el miembro original se oculte, mientrasoverride
extiende la implementación para un miembro heredado"Respuestas:
La palabra clave "nuevo" no anula, significa un nuevo método que no tiene nada que ver con el método de la clase base.
Esto imprime falso, si usó anulación, se habría impreso verdadero.
(Código base tomado de Joseph Daigle)
Entonces, si estás haciendo un verdadero polimorfismo, DEBES ANULAR SIEMPRE . El único lugar donde necesita usar "nuevo" es cuando el método no está relacionado de ninguna manera con la versión de la clase base.
fuente
virtual
en la base yoverride
en derivado? ¿Por qué existe? El código aún se ejecutará incluso sin /new
¿entonces, es puramente legible?Siempre encuentro cosas como esta más fáciles de entender con imágenes:
Nuevamente, tomando el código de Joseph Daigle,
Si luego llama al código de esta manera:
NOTA: Lo importante es que nuestro objeto es en realidad un
Bar
, pero lo estamos almacenando en una variable de tipoFoo
(esto es similar a lanzarlo)Entonces el resultado será el siguiente, dependiendo de si usó
virtual
/override
onew
al declarar sus clases.fuente
Aquí hay un código para comprender la diferencia en el comportamiento de los métodos virtuales y no virtuales:
fuente
new
para "ocultar" el método base, cuando simplemente no usar anulación parece hacer lo mismo?virtual
y el compilador se quejará si ve el mismo nombre de función en una clase "línea de sangre" sinvirtual
firmaLa
new
palabra clave realmente crea un miembro completamente nuevo que solo existe en ese tipo específico.Por ejemplo
El método existe en ambos tipos. Cuando usa la reflexión y obtiene los miembros de tipo
Bar
, en realidad encontrará 2 métodos llamadosDoSomething()
que se ven exactamente iguales. Al usarlonew
, oculta efectivamente la implementación en la clase base, de modo que cuando las clases se derivanBar
(en mi ejemplo), la llamada al métodobase.DoSomething()
vaBar
y noFoo
.fuente
virtual / override le dice al compilador que los dos métodos están relacionados y que, en algunas circunstancias, cuando crees que estás llamando al primer método (virtual), en realidad es correcto llamar al segundo método (anulado). Este es el fundamento del polimorfismo.
Llamará al método anulado VirtualFoo () de la Subclase.
new le dice al compilador que está agregando un método a una clase derivada con el mismo nombre que un método en la clase base, pero que no tienen relación entre sí.
Llamará al método NewBar () de BaseClass, mientras que:
Llamará al método NewBar () de la Subclase.
fuente
Más allá de solo los detalles técnicos, creo que el uso de virtual / override comunica mucha información semántica sobre el diseño. Cuando declara un método virtual, indica que espera que las clases de implementación quieran proporcionar sus propias implementaciones no predeterminadas. Omitir esto en una clase base, asimismo, declara la expectativa de que el método predeterminado debería ser suficiente para todas las clases de implementación. Del mismo modo, se pueden usar declaraciones abstractas para forzar la implementación de clases para proporcionar su propia implementación. Nuevamente, creo que esto comunica mucho acerca de cómo el programador espera que se use el código. Si escribiera tanto las clases básicas como las de implementación y me encontrara usando nuevas, volvería a pensar seriamente en la decisión de no hacer que el método sea virtual en los padres y declare mi intención específicamente.
fuente
La diferencia entre la palabra clave de anulación y la nueva palabra clave es que la primera anula el método y la segunda oculta el método.
Consulte los siguientes enlaces para obtener más información ...
MSDN y otros
fuente
new
La palabra clave es para ocultar. - significa que está ocultando su método en tiempo de ejecución. La salida se basará en el método de la clase base.override
para anular. - significa que está invocando su método de clase derivada con la referencia de la clase base. La salida se basará en el método de clase derivada.fuente
Mi versión de la explicación proviene del uso de propiedades para ayudar a comprender las diferencias.
override
es lo suficientemente simple, ¿verdad? El tipo subyacente anula el del padre.new
es quizás el engañoso (para mí lo fue). Con propiedades es más fácil de entender:Al usar un depurador puede notar que
Foo foo
tiene 2GetSomething
propiedades, ya que en realidad tiene 2 versiones de la propiedad,Foo
'syBar
', y para saber cuál usar, c # "selecciona" la propiedad para el tipo actual.Si quisieras usar la versión de la barra, hubieras usado anular o usar
Foo foo
en su lugar.Bar bar
tiene solo 1 , ya que quiere un comportamiento completamente nuevo paraGetSomething
.fuente
No marcar un método con nada significa: vincular este método utilizando el tipo de compilación del objeto, no el tipo de tiempo de ejecución (enlace estático).
Marcar un método con
virtual
medios: enlace este método utilizando el tipo de tiempo de ejecución del objeto, no el tipo de tiempo de compilación (enlace dinámico).Marcar un
virtual
método de clase base conoverride
en clase derivada significa: Este es el método a vincular utilizando el tipo de tiempo de ejecución del objeto (enlace dinámico).Marcar un
virtual
método de clase base connew
en clase derivada significa: Este es un método nuevo, que no tiene relación con el que tiene el mismo nombre en la clase base y debe vincularse usando el tipo de tiempo de compilación del objeto (enlace estático).No marcar un
virtual
método de clase base en la clase derivada significa: Este método está marcado comonew
(enlace estático).Marcar un método
abstract
significa: Este método es virtual, pero no declararé un cuerpo para él y su clase también es abstracta (enlace dinámico).fuente