Control de versiones con las palabras clave Override y New (Guía de programación de C#)Versioning with the Override and New Keywords (C# Programming Guide)

El lenguaje C# está diseñado para que las versiones entre clases base y derivadas de diferentes bibliotecas puedan evolucionar y mantener la compatibilidad con versiones anteriores.The C# language is designed so that versioning between base and derived classes in different libraries can evolve and maintain backward compatibility. 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 lleva a un comportamiento inesperado.This means, for example, that the introduction of a new member in a base class with the same name as a member in a derived class is completely supported by C# and does not lead to unexpected behavior. Además, implica que una clase debe declarar explícitamente si un método está pensado para reemplazar un método heredado o si se trata de un nuevo método que oculta un método heredado de nombre similar.It also means that a class must explicitly state whether a method is intended to override an inherited method, or whether a method is a new method that hides a similarly named inherited method.

En C#, las clases derivadas pueden contener métodos con el mismo nombre que los métodos de clase base.In C#, derived classes can contain methods with the same name as base class methods.

  • El método de clase base debe definirse como virtual.The base class method must be defined virtual.

  • Si el método de la clase derivada no va precedido por las palabras clave new u override, el compilador emite una advertencia y el método se comporta como si la palabra clave new estuviese presente.If the method in the derived class is not preceded by new or override keywords, the compiler will issue a warning and the method will behave as if the new keyword were present.

  • Si el método de la clase derivada va precedido de la palabra clave new, el método se define como independiente del método de la clase base.If the method in the derived class is preceded with the new keyword, the method is defined as being independent of the method in the base class.

  • Si el método de la clase derivada va precedido de la palabra clave override, los objetos de la clase derivada llamarán a ese método y no al método de la clase base.If the method in the derived class is preceded with the override keyword, objects of the derived class will call that method instead of the base class method.

  • El método de clase base puede llamarse desde dentro de la clase derivada mediante la palabra clave base.The base class method can be called from within the derived class using the base keyword.

  • Las palabras clave override, virtual y new también pueden aplicarse a propiedades, indexadores y eventos.The override, virtual, and new keywords can also be applied to properties, indexers, and events.

De forma predeterminada, los métodos de C# no son virtuales.By default, C# methods are not virtual. Si se declara un método como virtual, toda clase que hereda el método puede implementar su propia versiónIf a method is declared as virtual, any class inheriting the method can implement its own version. Para que un método sea virtual, se usa el modificador virtual en la declaración del método de la clase base.To make a method virtual, the virtual modifier is used in the method declaration of the base class. La clase derivada puede luego reemplazar el método base virtual mediante la palabra clave override u ocultar el método virtual en la clase base mediante la palabra clave new.The derived class can then override the base virtual method by using the override keyword or hide the virtual method in the base class by using the new keyword. Si no se especifican las palabras clave override o new, el compilador emite una advertencia y el método de la clase derivada oculta el método de la clase base.If neither the override keyword nor the new keyword is specified, the compiler will issue a warning and the method in the derived class will hide the method in the base class.

Para demostrar esto en la práctica, supongamos por un momento que la compañía A ha creado una clase denominada GraphicsClass, que su programa usa.To demonstrate this in practice, assume for a moment that Company A has created a class named GraphicsClass, which your program uses. La siguiente es GraphicsClass:The following is GraphicsClass:

class GraphicsClass
{
    public virtual void DrawLine() { }
    public virtual void DrawPoint() { }
}

Su compañía usa esta clase y usted la usa para derivar su propia clase, agregando un nuevo método:Your company uses this class, and you use it to derive your own class, adding a new method:

class YourDerivedGraphicsClass : GraphicsClass
{
    public void DrawRectangle() { }
}

La aplicación se usa sin problemas, hasta que la compañía A lanza una nueva versión de GraphicsClass, que es similar al código siguiente:Your application is used without problems, until Company A releases a new version of GraphicsClass, which resembles the following code:

class GraphicsClass
{
    public virtual void DrawLine() { }
    public virtual void DrawPoint() { }
    public virtual void DrawRectangle() { }
}

La nueva versión de GraphicsClass contiene ahora un método denominado DrawRectangle.The new version of GraphicsClass now contains a method named DrawRectangle. Inicialmente, no sucede nada.Initially, nothing occurs. La nueva versión sigue siendo compatible a nivel binario con la versión anterior.The new version is still binary compatible with the old version. Cualquier software que haya implementado seguirá funcionando, aunque la nueva clase se instale en esos sistemas informáticos.Any software that you have deployed will continue to work, even if the new class is installed on those computer systems. Cualquier llamada existente al método DrawRectangle seguirá haciendo referencia a su versión en la clase derivada.Any existing calls to the method DrawRectangle will continue to reference your version, in your derived class.

Pero en cuanto vuelva a compilar la aplicación con la nueva versión de GraphicsClass, recibirá una advertencia del compilador, CS0108.However, as soon as you recompile your application by using the new version of GraphicsClass, you will receive a warning from the compiler, CS0108. Esta advertencia le informa de que debe plantearse cómo quiere que el método DrawRectangle se comporte en la aplicación.This warning informs you that you have to consider how you want your DrawRectangle method to behave in your application.

Si quiere que su método reemplace al nuevo método de clase base, use la palabra clave override:If you want your method to override the new base class method, use the override keyword:

class YourDerivedGraphicsClass : GraphicsClass
{
    public override void DrawRectangle() { }
}

La palabra clave override se asegura de que los objetos derivados de YourDerivedGraphicsClass usen la versión de la clase derivada de DrawRectangle.The override keyword makes sure that any objects derived from YourDerivedGraphicsClass will use the derived class version of DrawRectangle. Los objetos derivados de YourDerivedGraphicsClass todavía pueden acceder a la versión de clase base DrawRectangle mediante la palabra clave base:Objects derived from YourDerivedGraphicsClass can still access the base class version of DrawRectangle by using the base keyword:

base.DrawRectangle();

Si no quiere que el método reemplace al nuevo método de clase base, se aplican las consideraciones siguientes.If you do not want your method to override the new base class method, the following considerations apply. Para evitar la confusión entre los dos métodos, puede cambiarle el nombre a su método.To avoid confusion between the two methods, you can rename your method. Esto puede ser un proceso lento y propenso a errores y no resultar práctico en algunos casos.This can be time-consuming and error-prone, and just not practical in some cases. Pero si el proyecto es relativamente pequeño, puede usar opciones de refactorización de Visual Studio para cambiar el nombre del método.However, if your project is relatively small, you can use Visual Studio's Refactoring options to rename the method. Para obtener más información, vea Refactoring Classes and Types (Class Designer) (Refactorización de clases y tipos [Diseñador de clases]).For more information, see Refactoring Classes and Types (Class Designer).

También puede evitar la advertencia mediante la palabra clave new en la definición de clase derivada:Alternatively, you can prevent the warning by using the keyword new in your derived class definition:

class YourDerivedGraphicsClass : GraphicsClass
{
    public new void DrawRectangle() { }
}

Con la palabra clave new se indica al compilador que su definición oculta la definición contenida en la clase base.Using the new keyword tells the compiler that your definition hides the definition that is contained in the base class. Éste es el comportamiento predeterminado.This is the default behavior.

Selección de método y reemplazoOverride and Method Selection

Cuando se llama a un método en una clase, el compilador de C# selecciona el mejor método para llamar si hay más de uno 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.When a method is named on a class, the C# compiler selects the best method to call if more than one method is compatible with the call, such as when there are two methods with the same name, and parameters that are compatible with the parameter passed. Los métodos siguientes serían compatibles:The following methods would be compatible:

public class Derived : Base
{
    public override void DoWork(int param) { }
    public void DoWork(double param) { }
}

Cuando se llama a DoWork en una instancia de Derived, el compilador de C# intentará en primer lugar que la llamada sea compatible con las versiones de DoWork declaradas originalmente en Derived.When DoWork is called on an instance of Derived, the C# compiler will first try to make the call compatible with the versions of DoWork declared originally on Derived. Los métodos de reemplazo no se consideran como declarados en una clase, son nuevas implementaciones de un método que se declara en una clase base.Override methods are not considered as declared on a class, they are new implementations of a method declared on a base class. Solo si el compilador de C# no puede hacer coincidir la llamada al método con un método original en Derived, intentará hacer coincidir la llamada con un método reemplazado con el mismo nombre y parámetros compatibles.Only if the C# compiler cannot match the method call to an original method on Derived will it try to match the call to an overridden method with the same name and compatible parameters. Por ejemplo:For example:

int val = 5;
Derived d = new Derived();
d.DoWork(val);  // Calls DoWork(double).

Dado que la variable val se puede convertir implícitamente en un valor doble, el compilador de C# llama a DoWork(double) en lugar de a DoWork(int).Because the variable val can be converted to a double implicitly, the C# compiler calls DoWork(double) instead of DoWork(int). Hay dos maneras de evitarlo.There are two ways to avoid this. En primer lugar, evite declarar nuevos métodos con el mismo nombre que los métodos virtuales.First, avoid declaring new methods with the same name as virtual methods. En segundo lugar, puede indicar al compilador de C# que llame al método virtual haciendo que busque la lista de métodos de clase base mediante la conversión de la instancia de Derived a Base.Second, you can instruct the C# compiler to call the virtual method by making it search the base class method list by casting the instance of Derived to Base. Como el método es virtual, se llamará a la implementación de DoWork(int) en Derived.Because the method is virtual, the implementation of DoWork(int) on Derived will be called. Por ejemplo:For example:

((Base)d).DoWork(val);  // Calls DoWork(int) on Derived.

Para obtener otros ejemplos de new y override, vea Knowing When to Use Override and New Keywords (Saber cuándo usar las palabras clave override y new [Guía de programación de C#]).For more examples of new and override, see Knowing When to Use Override and New Keywords.

Vea tambiénSee also