Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
El lenguaje C# está diseñado para que el control de versiones entre las clases base y derivadas de diferentes bibliotecas pueda evolucionar y mantener la compatibilidad con versiones anteriores. Esto significa, por ejemplo, que la introducción de un nuevo miembro en una clase base con el mismo nombre que un miembro de una clase derivada es totalmente compatible con C# y no conduce a un comportamiento inesperado. También significa que una clase debe indicar explícitamente si un método está diseñado para invalidar un método heredado o si un método es un nuevo método que oculta un método heredado con nombre similar.
En C#, las clases derivadas pueden contener métodos con el mismo nombre que los métodos de clase base.
Si el método de la clase derivada no está precedido de palabras clave nuevas o invalidadas , el compilador emitirá una advertencia y el método se comportará como si la
new
palabra clave estuviera presente.Si el método de la clase derivada está precedido de la
new
palabra clave , el método se define como independiente del método de la clase base.Si el método de la clase derivada está precedido de la
override
palabra clave , los objetos de la clase derivada llamarán a ese método en lugar del método de clase base.Para aplicar la
override
palabra clave al método de la clase derivada, el método de clase base debe definirse virtual.Se puede llamar al método de clase base desde dentro de la clase derivada mediante la
base
palabra clave .Las
override
palabras clave ,virtual
ynew
también se pueden aplicar a propiedades, indexadores y eventos.
De forma predeterminada, los métodos de C# no son virtuales. Si un método se declara como virtual, cualquier clase que herede el método puede implementar su propia versión. Para que un método sea virtual, el virtual
modificador se usa en la declaración de método de la clase base. A continuación, la clase derivada puede invalidar el método virtual base mediante la override
palabra clave u ocultar el método virtual en la clase base mediante la new
palabra clave . Si no se especifica la override
palabra clave ni la new
palabra clave , el compilador emitirá una advertencia y el método de la clase derivada ocultará el método en la clase base.
Para demostrar esto en la práctica, supongamos por un momento que la Empresa A ha creado una clase denominada GraphicsClass
, que usa el programa. La siguiente es GraphicsClass
:
class GraphicsClass
{
public virtual void DrawLine() { }
public virtual void DrawPoint() { }
}
Su empresa usa esta clase y la usa para derivar su propia clase, agregando un nuevo método:
class YourDerivedGraphicsClass : GraphicsClass
{
public void DrawRectangle() { }
}
La aplicación se usa sin problemas, hasta que la empresa A publica una nueva versión de GraphicsClass
, que se parece al código siguiente:
class GraphicsClass
{
public virtual void DrawLine() { }
public virtual void DrawPoint() { }
public virtual void DrawRectangle() { }
}
La nueva versión de GraphicsClass
ahora contiene un método denominado DrawRectangle
. Inicialmente, no ocurre nada. La nueva versión sigue siendo binaria compatible con la versión anterior. Cualquier software que haya implementado seguirá funcionando, incluso si la nueva clase está instalada en esos sistemas informáticos. Las llamadas existentes al método DrawRectangle
seguirán haciendo referencia a tu versión en la clase derivada.
Sin embargo, en cuanto vuelva a compilar la aplicación mediante la nueva versión de GraphicsClass
, recibirá una advertencia del compilador, CS0108. Esta advertencia le informa que debe considerar cómo desea que su método DrawRectangle
se comporte en su aplicación.
Si desea que el método invalide el nuevo método de clase base, use la override
palabra clave :
class YourDerivedGraphicsClass : GraphicsClass
{
public override void DrawRectangle() { }
}
La override
palabra clave garantiza que los objetos derivados de YourDerivedGraphicsClass
usarán la versión de clase derivada de DrawRectangle
. Los objetos derivados de YourDerivedGraphicsClass
todavía pueden tener acceso a la versión de clase base de DrawRectangle
mediante la palabra clave base:
base.DrawRectangle();
Si no desea que el método invalide el nuevo método de clase base, se aplican las siguientes consideraciones. Para evitar confusiones entre los dos métodos, puede cambiar el nombre del método. Esto puede ser lento y propenso a errores, y simplemente no práctico en algunos casos. Sin embargo, si el proyecto es relativamente pequeño, puede usar las opciones de refactorización de Visual Studio para cambiar el nombre del método. Para obtener más información, vea Refactorización de clases y tipos (Diseñador de clases).
Como alternativa, puede evitar la advertencia mediante la palabra clave new
en la definición de clase derivada:
class YourDerivedGraphicsClass : GraphicsClass
{
public new void DrawRectangle() { }
}
El uso de la new
palabra clave indica al compilador que la definición oculta la definición contenida en la clase base. Este es el comportamiento predeterminado.
Selección de método y reemplazo
Cuando se llama a un método en una clase, el compilador de C# selecciona el mejor método para llamar si más de un método es compatible con la llamada, como cuando hay dos métodos con el mismo nombre y parámetros que son compatibles con el parámetro pasado. Los métodos siguientes serían compatibles:
public class Derived : Base
{
public override void DoWork(int param) { }
public void DoWork(double param) { }
}
Cuando DoWork
se llama a en una instancia de Derived
, el compilador de C# intentará primero hacer que la llamada sea compatible con las versiones de DoWork
declaradas originalmente en Derived
. Los métodos de invalidación no se consideran declarados en una clase, son nuevas implementaciones de un método declarado en una clase base. Solo si el compilador de C# no puede coincidir con la llamada de método a un método original en Derived
, intentará hacer coincidir la llamada a un método invalidado con el mismo nombre y parámetros compatibles. Por ejemplo:
int val = 5;
Derived d = new();
d.DoWork(val); // Calls DoWork(double).
Dado que la variable val
se puede convertir a un doble implícitamente, el compilador de C# llama a DoWork(double)
en lugar de DoWork(int)
. Hay dos maneras de evitar esto. En primer lugar, evite declarar nuevos métodos con el mismo nombre que los métodos virtuales. En segundo lugar, puede indicar al compilador de C# que llame al método virtual haciendo que busque en la lista de métodos de clase base mediante la conversión de la instancia de Derived
en Base
. Como el método es virtual, se llamará a la implementación de DoWork(int)
en Derived
. Por ejemplo:
((Base)d).DoWork(val); // Calls DoWork(int) on Derived.
Para obtener otros ejemplos de new
y override
, vea Saber cuándo utilizar las palabras clave Override y New (Guía de programación de C#).