Access-Basisklassenmember aus einer abgeleiteten Klasse
Eine abgeleitete Klasse, die eine Basisklassenmethode oder -eigenschaft ersetzt oder überschreibt, kann weiterhin mithilfe des schlüsselworts base auf die Methode oder Eigenschaft der Basisklasse zugreifen. Auf diese Weise können Sie Basisklassenkonstruktoren, Methoden und Eigenschaften von überschriebenen Elementen einer abgeleiteten Klasse aufrufen. Mithilfe des schlüsselworts base können Sie sicherstellen, dass die abgeleitete Klasse die von der Basisklasse bereitgestellte Funktionalität ordnungsgemäß wiederverwendet und erweitert.
Das schlüsselwort base wird verwendet, um die folgenden Aufgaben auszuführen:
- So rufen Sie eine Basisklassenmethode aus einer überschriebenen Methode der abgeleiteten Klasse auf.
- So implementieren Sie einen Basisklassenkonstruktor aus dem Konstruktor der abgeleiteten Klasse.
Das Schlüsselwort base weist die folgenden Einschränkungen auf:
- Das schlüsselwort
basekann nur in einem Konstruktor, einer Instanzmethode oder einem Instanzeigenschaftsaccessor verwendet werden. - Das schlüsselwort
basekann nicht in einer statischen Methode verwendet werden. Wenn Sie versuchen, das schlüsselwortbasein einer statischen Methode zu verwenden, wird ein Fehler generiert.
Wenn Sie das schlüsselwort base in einer abgeleiteten Klasse implementieren, verwendet Ihr Code die in der Klassendeklaration angegebene Basisklasse. Wenn Sie z. B. die Klasse ClassC : ClassB in der Klassendeklaration angeben, ermöglicht das schlüsselwort base Ihrem Code den Zugriff auf die Member von ClassB aus ClassC. Es spielt keine Rolle, ob die Klasse ClassB von der Klasse ClassAerbt.
Access-Basisklasseneigenschaften und -methoden aus einer abgeleiteten Klasse
Der Zugriff auf die Eigenschaften und Methoden einer Basisklasse aus einer abgeleiteten Klasse ist eine häufige Anforderung bei der Implementierung der Vererbung. Der folgende Code veranschaulicht die Syntax für die Implementierung des schlüsselworts base:
base.MemberName
Beachten Sie, dass das schlüsselwort base und der Name des Basisklassenelements durch einen Punkt (.) getrennt sind. Die MemberName kann eine Eigenschaft, Methode oder ein Feld der Basisklasse sein.
Der folgende Code veranschaulicht, wie Sie auf Basisklasseneigenschaften und -methoden aus einer abgeleiteten Klasse zugreifen:
// 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;
}
}
In diesem Codebeispiel erbt die DerivedClass1-Klasse von der BaseClass und überschreibt die Methoden, um ihre Funktionalität zu erweitern. Der Code implementiert die folgenden Schritte:
Eine Instanz von
DerivedClass1wird mithilfe der AnweisungDerivedClass1 derivedClass1 = new DerivedClass1();erstellt. Diese abgeleitete Klasseninstanz wird verwendet, um die überschriebenen Methoden der abgeleiteten Klasse aufzurufen und zu veranschaulichen.Der Code ruft
Method1der abgeleiteten Klasse aus einerConsole.WriteLine-Anweisung auf. Der AußerkraftsetzungszugriffMethod1kann nicht auf die AbstraktionMethod1der Basisklasse zugreifen. Stattdessen wird eine eigene Implementierung bereitgestellt, die eine Zeichenfolge zurückgibt, die angibt, dass sie für die abgeleitete Klasse eindeutig ist.Der Code ruft
Method2der abgeleiteten Klasse auf. Die überschriebeneMethod2verwendetbase.Method2, um dieMethod2Implementierung der Basisklasse wiederzuverwenden. Die Methode greift auf dieProperty2der Basisklasse zu und druckt den Wert. Die überschriebene Methode verwendet dann den booleschen Wert, der vomMethod2der Basisklasse und dem Wert vonProperty2zurückgegeben wird, um entweder dieMethod2-Funktionalität zu erweitern oder ein alternatives Verhalten zu implementieren. In diesem Schritt wird veranschaulicht, wie die abgeleitete Klasse auf dem Verhalten der Basisklassenmethode aufbauen und ändern kann.
Anmerkung
Es wird empfohlen, dass virtuelle Member base verwenden, um die Basisklassenimplementierung dieses Elements in ihrer eigenen Implementierung aufzurufen. Das Auftreten des Basisklassenverhaltens ermöglicht es der abgeleiteten Klasse, sich auf das implementierungsspezifische Verhalten der abgeleiteten Klasse zu konzentrieren. Wenn die Basisklassenimplementierung nicht aufgerufen wird, liegt es an der abgeleiteten Klasse, ihr Verhalten mit dem Verhalten der Basisklasse kompatibel zu machen.
Access-Basisklassenkonstruktoren aus einer abgeleiteten Klasse
Auf Klassenkonstruktoren in der Basisklasse kann über Konstruktoren der abgeleiteten Klasse mithilfe des schlüsselworts base zugegriffen werden.
Der folgende Code veranschaulicht, wie Sie auf Basisklassenkonstruktoren aus einer abgeleiteten Klasse zugreifen:
// 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;
}
}
Das Aufrufen des Basisklassenkonstruktors aus dem abgeleiteten Klassenkonstruktor ist wichtig. Wenn der Basisklassenkonstruktor beispielsweise allgemeine Eigenschaften initialisiert, die von der abgeleiteten Klasse verwendet werden. Durch Aufrufen des Basisklassenkonstruktors aus dem abgeleiteten Klassenkonstruktor stellen Sie sicher, dass die allgemeinen Eigenschaften initialisiert werden, bevor der abgeleitete Klassenkonstruktor ausgeführt wird.
Beachten Sie den folgenden Code:
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();
}
}
Beachten Sie, dass der Car Klassenkonstruktor den Basisklassenkonstruktor mithilfe des schlüsselworts base aufruft. Durch aufrufen des Basisklassenkonstruktors wird zuerst sichergestellt, dass die eigenschaften Speed und Fuel der Vehicle Basisklasse ordnungsgemäß initialisiert werden, bevor der Car Klassenkonstruktor ausgeführt wird. Diese Abfolge von Ereignissen ist wichtig, da die TrunkCapacity Eigenschaft der Car-Klasse mithilfe der eigenschaften Speed und Fuel der Vehicle Basisklasse initialisiert wird.
Zusammenfassung
Beachten Sie beim Zugriff auf Basisklassenmember aus einer abgeleiteten Klasse die folgenden Richtlinien:
- Verwenden Sie das schlüsselwort
base, um auf Basisklassenmember aus einer abgeleiteten Klasse zuzugreifen. - Verwenden Sie das schlüsselwort
base, um Basisklassenkonstruktoren aus abgeleiteten Klassenkonstruktoren aufzurufen. - Verwenden Sie das schlüsselwort
basefür den Zugriff auf Basisklassenfelder, -eigenschaften und -methoden aus überschriebenen Methoden in einer abgeleiteten Klasse.