Obtener acceso a los miembros de clase base desde una clase derivada
Una clase derivada que reemplaza o invalida un método o propiedad de clase base todavía puede tener acceso al método o la propiedad en la clase base mediante la palabra clave base. Esto permite llamar a constructores, métodos y propiedades de clase base de miembros invalidados de una clase derivada. Mediante el uso de la palabra clave base, puede asegurarse de que la clase derivada reutiliza y amplía de forma correcta la funcionalidad proporcionada por la clase base.
La palabra clave base se usa para realizar las siguientes tareas:
- Para llamar a un método de clase base desde un método invalidado de la clase derivada.
- Para implementar un constructor de clase base desde dentro del constructor de la clase derivada.
La palabra clave base tiene las restricciones siguientes:
- La palabra clave
basesolo se puede usar en un constructor, un método de instancia o un descriptor de acceso de propiedad de instancia. - La palabra clave
baseno se puede usar en un método estático. Si intenta usar la palabra clavebaseen un método estático, se generará un error.
Al implementar la palabra clave base en una clase derivada, el código usa la clase base especificada en la declaración de clase. Por ejemplo, si especifica la clase ClassC : ClassB en la declaración de clase, la palabra clave base permite que el código acceda a los miembros de ClassB desde ClassC. No importa si la clase ClassB hereda de la clase ClassA.
Acceso a propiedades y métodos de clase base desde una clase derivada
El acceso a las propiedades y métodos de una clase base desde una clase derivada es un requisito común al implementar la herencia. En el código siguiente se muestra la sintaxis para implementar la palabra clave base:
base.MemberName
Observe que la palabra clave base y el nombre del miembro de clase base están separados por un punto (.).
MemberName puede ser una propiedad, un método o un campo de la clase base.
En el código siguiente se muestra cómo obtener acceso a las propiedades y métodos de clase base desde una clase derivada:
// create an instance of the derived classes
DerivedClass1 derivedClass1 = new DerivedClass1();
// demonstrate the overridden methods of the derived class
Console.WriteLine("Calling the methods of DerivedClass1...\n");
Console.WriteLine($"Method1 in the derived class overrides the base class and provides a custom message: {derivedClass1.Method1()}");
derivedClass1.Method2();
/*Output:
Calling the methods of DerivedClass1...
Method1 in the base class is abstract and can't be called.
Method1 in the derived class overrides the base class and provides a custom message: Message from the overridden Method1 in DerivedClass1
Method2 in the derived class calls base.Method2 (reuses the base class implementation)
Method2 in the base class implements common behavior and returns true/false
Method2 in the derived class accesses base class Property2: Base - Property2
Method2 in the derived class uses base class members to modify and extend functionality
*/
public abstract class BaseClass
{
public abstract string Property1 { get; set; }
public virtual string Property2 { get; set; } = "Base - Property2";
public abstract string Method1();
public virtual bool Method2()
{
Console.WriteLine("Method2 in the base class implements common behavior and returns true/false");
return true;
}
}
public class DerivedClass1 : BaseClass
{
public override string Property1 { get; set; } = "Derived - Property1";
public new string Property2 { get; set; } = "Derived - Property2";
public override string Method1()
{
// Method1 of the base class is abstract and can't be called
Console.WriteLine($"Method1 in the base class is abstract and can't be called.");
// Return the base.Method1 response additional information specific to DerivedClass1
return $"Message from the overridden Method1 in DerivedClass1";
}
public override bool Method2()
{
// Call base class method to implement common behavior
Console.WriteLine($"\nMethod2 in the derived class calls base.Method2 (reuses the base class implementation)");
bool baseMethod2Success = base.Method2();
// Access base class Property2
string baseProperty2Value = base.Property2;
Console.WriteLine($"Method2 in the derived class accesses base class Property2: {baseProperty2Value}");
// implement derived class logic that involves base class information
if (baseMethod2Success && baseProperty2Value == "Base - Property2")
{
Console.WriteLine("\nMethod2 in the derived class uses base class members to modify and extend functionality");
return true;
}
else
{
Console.WriteLine("Method2 in the derived class can implement alternate behavior");
}
return false;
}
}
En este ejemplo de código, la clase DerivedClass1 hereda de BaseClass e invalida sus métodos para ampliar su funcionalidad. El código implementa los pasos siguientes:
Se crea una instancia de
DerivedClass1mediante la instrucciónDerivedClass1 derivedClass1 = new DerivedClass1();. Esta instancia de clase derivada se usa para llamar a y demostrar los métodos invalidados de la clase derivada.El código llama a la clase
Method1derivada desde dentro de una instrucciónConsole.WriteLine. El invalidadoMethod1no puede tener acceso al resumenMethod1de la clase base. En su lugar, proporciona su propia implementación que devuelve una cadena que indica que es única para la clase derivada.El código llama a
Method2la clase derivada. La invalidadaMethod2usabase.Method2para reutilizar la implementación de la clase baseMethod2. El método accede alProperty2de la clase base e imprime su valor. A continuación, el método invalidado usa el valor booleano devuelto por elMethod2de la clase base y el valor deProperty2, para ampliar la funcionalidad deMethod2o implementa un comportamiento alternativo En este paso se muestra cómo la clase derivada puede basar y modificar el comportamiento del método de clase base.
Nota
Se recomienda a los miembros virtuales usen base para llamar a la implementación de clase base de ese miembro en su propia implementación. Permitir que se produzca el comportamiento de la clase base permite que la clase derivada se centre en la implementación del comportamiento específico de la clase derivada. Si no se llama a la implementación de la clase base, es hasta la clase derivada para que su comportamiento sea compatible con el comportamiento de la clase base.
Acceso a constructores de clase base desde una clase derivada
Se puede acceder a los constructores de clase de la clase base desde constructores de la clase derivada mediante la palabra clave base.
En el código siguiente se muestra cómo acceder a constructores de clase base desde una clase derivada:
// create an instance of the derived classes
DerivedClass1 derivedClass1 = new DerivedClass1("Derived1 - Property1", "Derived1 - Property2");
// demonstrate the overridden methods of the derived class
Console.WriteLine("Calling the methods of DerivedClass1...\n");
Console.WriteLine($"Method1 in the derived class appends derived class information to the return value: {derivedClass1.Method1()}");
derivedClass1.Method2();
/*Output:
Calling the methods of DerivedClass1...
Method1 in the derived class calls base.Method1. base.Method1 returns: base.Method1 results
Method1 in the derived class appends derived class information to the return value: base.Method1 results - plus information specific to DerivedClass1
Method2 in the derived class calls base.Method2 (reuses the base class implementation)
Method2 in the base class implements common behavior and returns true/false
Method2 in the derived class accesses base class Property2: Base - Property2
Method2 in the derived class uses base class members to modify and extend functionality
*/
public abstract class BaseClass
{
public abstract string Property1 { get; set; }
public virtual string Property2 { get; set; }
public BaseClass(string property1, string property2)
{
Property1 = property1;
Property2 = property2;
}
public virtual string Method1()
{
return "base.Method1 results";
}
public virtual bool Method2()
{
Console.WriteLine("Method2 in the base class implements common behavior and returns true/false");
return true;
}
}
public class DerivedClass1 : BaseClass
{
public override string Property1 { get; set; }
public new string Property2 { get; set; }
public DerivedClass1(string property1, string property2) : base(property1, "Base - Property2")
{
Property1 = property1;
Property2 = property2;
}
public override string Method1()
{
// Method1 of the base class is now virtual
Console.WriteLine($"Method1 in the derived class calls base.Method1. base.Method1 returns: {base.Method1()}");
// Return the base.Method1 response additional information specific to DerivedClass1
return $"{base.Method1()} - plus information specific to DerivedClass1";
}
public override bool Method2()
{
// Call base class method to implement common behavior
Console.WriteLine($"\nMethod2 in the derived class calls base.Method2 (reuses the base class implementation)");
bool baseMethod1Success = base.Method2();
// Access base class Property2
string baseProperty2Value = base.Property2;
Console.WriteLine($"Method2 in the derived class accesses base class Property2: {baseProperty2Value}");
// implement derived class logic that involves base class information
if (baseMethod1Success && baseProperty2Value == "Base - Property2")
{
Console.WriteLine("\nMethod2 in the derived class uses base class members to modify and extend functionality");
return true;
}
else
{
Console.WriteLine("Method2 in the derived class can implement alternate behavior");
}
return false;
}
}
Es importante llamar al constructor de clase base desde el constructor de clase derivada. Por ejemplo, cuando el constructor de clase base inicializa las propiedades comunes que usa la clase derivada. Al llamar al constructor de clase base desde el constructor de clase derivada, asegúrese de que las propiedades comunes se inicializan antes de que se ejecute el constructor de clase derivada.
Tenga en cuenta el código siguiente:
public abstract class Vehicle
{
public virtual int Speed { get; set; }
public virtual int Fuel { get; set; }
public Vehicle(int speed, int fuel)
{
Speed = speed;
Fuel = fuel;
}
public virtual void Drive()
{
Console.WriteLine("Vehicle is driving");
}
}
public class Car : Vehicle
{
public int NumberOfDoors { get; set; }
public int TrunkCapacity { get; set; }
public Car(int speed, int fuel, int numberOfDoors) : base(speed, fuel)
{
NumberOfDoors = numberOfDoors;
// Initialize TrunkCapacity based on the Speed and Fuel properties of the base class
TrunkCapacity = CalculateTrunkCapacity(Speed, Fuel);
}
private int CalculateTrunkCapacity(int speed, int fuel)
{
// Example logic to calculate trunk capacity based on speed and fuel
return (speed + fuel) / 2;
}
public override void Drive()
{
base.Drive();
Console.WriteLine("Car is driving with additional features");
}
}
class Program
{
static void Main()
{
Car car = new Car(100, 50, 4);
Console.WriteLine($"Speed: {car.Speed}, Fuel: {car.Fuel}, NumberOfDoors: {car.NumberOfDoors}, TrunkCapacity: {car.TrunkCapacity}");
car.Drive();
}
}
Observe que el constructor de clase Car llama al constructor de clase base mediante la palabra clave base. Llamar primero al constructor de clase base garantiza que las propiedades Speed y Fuel de la clase base de Vehicle se inicializan correctamente antes de que se ejecute el Car constructor de clase. Esta secuencia de eventos es importante porque la propiedad TrunkCapacity de la clase Car se inicializa mediante las propiedades Speed y Fuel de la clase base Vehicle.
Resumen
Tenga en cuenta las instrucciones siguientes al acceder a los miembros de clase base desde una clase derivada:
- Use la palabra clave
basepara tener acceso a los miembros de clase base desde una clase derivada. - Use la palabra clave
basepara llamar a constructores de clase base de constructores de clase derivadas. - Use la palabra clave
basepara acceder a los campos, propiedades y métodos de clase base de métodos invalidados en una clase derivada.