Toegang tot basisklasseleden van een afgeleide klasse

Voltooid

Een afgeleide klasse die een basisklassemethode of -eigenschap vervangt of overschrijft, heeft nog steeds toegang tot de methode of eigenschap in de basisklasse met behulp van het trefwoord base. Hiermee kunt u basisklasseconstructors, methoden en eigenschappen aanroepen van overschreven leden van een afgeleide klasse. Met behulp van het trefwoord base kunt u ervoor zorgen dat de afgeleide klasse de functionaliteit van de basisklasse correct hergebruikt en uitbreidt.

Het trefwoord base wordt gebruikt om de volgende taken uit te voeren:

  • Een basisklassemethode aanroepen vanuit een overschreven methode van de afgeleide klasse.
  • Een baseklasse-constructor implementeren vanuit de constructor van de afgeleide klasse.

Het trefwoord base heeft de volgende beperkingen:

  • Het base trefwoord kan alleen worden gebruikt in een constructor, een instantiemethode of een instantieeigenschapstoegangsor.
  • Het trefwoord base kan niet worden gebruikt in een statische methode. Als u het base trefwoord in een statische methode probeert te gebruiken, wordt er een fout gegenereerd.

Wanneer u het base trefwoord in een afgeleide klasse implementeert, gebruikt uw code de basisklasse die is opgegeven in de klassedeclaratie. Als u bijvoorbeeld klasse-ClassC : ClassB opgeeft in de klassedeclaratie, kunt u met het base trefwoord toegang krijgen tot de leden van ClassB vanuit ClassC. Het maakt niet uit of klasse ClassB overgaat van klasse ClassA.

Basisklasse-eigenschappen en -methoden van een afgeleide klasse openen

Toegang tot de eigenschappen en methoden van een basisklasse van een afgeleide klasse is een algemene vereiste bij het implementeren van overname. In de volgende code ziet u de syntaxis voor het implementeren van het trefwoord base:

base.MemberName

U ziet dat het base trefwoord en de naam van het lid van de basisklasse worden gescheiden door een punt (.). De MemberName kan een eigenschap, methode of veld van de basisklasse zijn.

De volgende code laat zien hoe u toegang hebt tot eigenschappen en methoden van basisklassen van een afgeleide klasse:


// 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 dit codevoorbeeld neemt de DerivedClass1 klasse de BaseClass over en overschrijft de methoden om hun functionaliteit uit te breiden. De code implementeert de volgende stappen:

  1. Er wordt een exemplaar van DerivedClass1 gemaakt met behulp van de instructie DerivedClass1 derivedClass1 = new DerivedClass1();. Dit afgeleide klasse-exemplaar wordt gebruikt om de overschreven methoden van de afgeleide klasse aan te roepen en te demonstreren.

  2. De code roept Method1 van de afgeleide klasse aan vanuit een Console.WriteLine instructie. De onderdrukking Method1 heeft geen toegang tot het abstracte Method1 van de basisklasse. In plaats daarvan biedt het een eigen implementatie die een tekenreeks retourneert die aangeeft dat deze uniek is voor de afgeleide klasse.

  3. De code roept Method2 van de afgeleide klasse aan. De overschreven Method2 gebruikt base.Method2 om de Method2-implementatie van de basisklasse opnieuw te gebruiken. De methode opent de Property2 van de basisklasse en drukt de waarde ervan af. De overschreven methode gebruikt vervolgens de Booleaanse waarde die wordt geretourneerd door de Method2 van de basisklasse en de waarde van Property2, om de Method2-functionaliteit uit te breiden of alternatief gedrag te implementeren. In deze stap ziet u hoe de afgeleide klasse het gedrag van de basisklassemethode kan uitbreiden en wijzigen.

Notitie

Het is een aanbevolen procedure voor virtuele leden om base te gebruiken om de basisklasse-implementatie van dat lid aan te roepen in hun eigen implementatie. Door het gedrag van de basisklasse op te laten treden, kan de afgeleide klasse zich concentreren op het implementeren van gedrag dat specifiek is voor de afgeleide klasse. Als de implementatie van de basisklasse niet wordt aangeroepen, is het aan de afgeleide klasse om hun gedrag compatibel te maken met het gedrag van de basisklasse.

Toegang tot basisklasseconstructors van een afgeleide klasse

Klasseconstructors in de basisklasse kunnen worden geopend vanuit constructors van de afgeleide klasse met behulp van het trefwoord base.

De volgende code laat zien hoe u toegang hebt tot basisklasseconstructors van een afgeleide klasse:


// 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;
    }
}

Het aanroepen van de basisklasseconstructor van de afgeleide klasseconstructor is belangrijk. Wanneer de basisklasseconstructor bijvoorbeeld algemene eigenschappen initialiseert die worden gebruikt door de afgeleide klasse. Door de basisklasseconstructor aan te roepen vanuit de afgeleide klasseconstructor, zorgt u ervoor dat de algemene eigenschappen worden geïnitialiseerd voordat de afgeleide klasseconstructor wordt uitgevoerd.

Houd rekening met de volgende 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();
    }
}

U ziet dat de Car klasseconstructor de basisklasseconstructor aanroept met behulp van het trefwoord base. Als u eerst de basisklasseconstructor aanroept, zorgt u ervoor dat de eigenschappen van de Speed en Fuel van de Vehicle basisklasse correct worden geïnitialiseerd voordat de Car klasseconstructor wordt uitgevoerd. Deze reeks gebeurtenissen is belangrijk omdat de eigenschap TrunkCapacity van de Car-klasse wordt geïnitialiseerd met behulp van de Speed- en Fuel eigenschappen van de Vehicle basisklasse.

Samenvatting

Houd rekening met de volgende richtlijnen bij het openen van basisklasseleden van een afgeleide klasse:

  • Gebruik het trefwoord base om toegang te krijgen tot basisklasseleden van een afgeleide klasse.
  • Gebruik het trefwoord base om basisklasseconstructors aan te roepen van afgeleide klasseconstructors.
  • Gebruik het trefwoord base om toegang te krijgen tot basisklassevelden, eigenschappen en methoden van overschreven methoden in een afgeleide klasse.