Konfigurer basisklasser og avledede klasser

Fullført

Begrepene basisklasse og avledet klasse brukes til å beskrive forholdet mellom klasser i et arvehierarki. En basisklasse brukes til å definere et felles sett med attributter og virkemåter som andre klasser arver. En avledet klasse brukes til å definere et spesialisert sett med attributter og virkemåter som utvider eller endrer basisklassen.

Undersøk arvens transitive natur

I C#kan en klasse arve fra bare én basisklasse. Denne begrensningen kalles enkel arv. Enkel arv gir en avledet klasse tilgang til egenskapene og metodene til én enkelt basisklasse, noe som fremmer et klart og enkelt hierarki. Konseptet med flere arv støttes ikke i C#. Denne begrensningen unngår kompleksiteten og tvetydighetene som kan oppstå når du arver fra flere basisklasser. I stedet bruker C# grensesnitt for å oppnå lignende funksjonalitet.

Selv om en klasse bare kan arve fra én basisklasse, er arv transitiv. Dette betyr at hvis en klasse C arver fra klasse B og klasse B arver fra klasse A, arver klasse C medlemmene som er deklarert i både klasse B og klasse A. Denne egenskapen gir dypere hierarkier og videre gjenbruk av kode.

Vurder for eksempel et kjøretøystyringssystem der du har en basisklasse Vehicle, en avledet klasse Car som arver fra Vehicle, og en annen avledet klasse ElectricCar som arver fra Car. I dette hierarkiet arver ElectricCar medlemmer fra både Car og Vehicle, som demonstrerer arvemets transitive natur.

public class Vehicle
{
    public string Make { get; set; }
    public string Model { get; set; }

    public void StartEngine()
    {
        Console.WriteLine("Engine started.");
    }

    public void StopEngine()
    {
        Console.WriteLine("Engine stopped.");
    }
}

public class Car : Vehicle
{
    public int NumberOfDoors { get; set; }

    public void OpenTrunk()
    {
        Console.WriteLine("Trunk opened.");
    }

    public void HonkHorn()
    {
        Console.WriteLine("Horn honked.");
    }

    public void LockDoors()
    {
        Console.WriteLine("Doors locked.");
    }
}

public class ElectricCar : Car
{
    public int BatteryCapacity { get; set; }

    public void ChargeBattery()
    {
        Console.WriteLine("Battery charging.");
    }

    public void DisplayBatteryStatus()
    {
        Console.WriteLine("Battery status displayed.");
    }
}

public class CombustionEngineCar : Car
{
    public int FuelCapacity { get; set; }

    public void Refuel()
    {
        Console.WriteLine("Car refueled.");
    }

    public void CheckOilLevel()
    {
        Console.WriteLine("Oil level checked.");
    }
}

Dette eksemplet viser et enkelt kjøretøystyringssystem med følgende klasser:

  • Vehicle klasse: Basisklassen Vehicle inneholder vanlige egenskaper og metoder for alle kjøretøy, for eksempel Merke, Modell, StartEngine og StopEngine.

  • Car klasse: Car klassen arver fra Vehicle og legger til spesifikke egenskaper og metoder for biler, for eksempel NumberOfDoors, OpenTrunk, HonkHornog LockDoors.

  • ElectricCar klasse: ElectricCar klassen arver fra Car og legger til egenskaper og metoder som er spesifikke for elbiler, for eksempel BatteryCapacity, ChargeBatteryog DisplayBatteryStatus.

  • CombustionEngineCar klasse: CombustionEngineCar klassen arver også fra Car og legger til egenskaper og metoder som er spesifikke for forbrenningsmotorbiler, for eksempel FuelCapacity, Refuelog CheckOilLevel.

I dette eksemplet arver Car klassen medlemmer fra Vehicle klassen, og ElectricCar og CombustionEngineCar arver medlemmer fra Car klassen. Dette hierarkiet demonstrerer arvens transitive natur, der ElectricCar og CombustionEngineCar arver medlemmer fra både Car og Vehicle.

Undersøk medlemsarv og synlighet

Når en klasse arver fra en basisklasse, gjelder følgende regler:

  • Statiske konstruktører og forekomstkonstruktører arves ikke.
  • Alle andre medlemmer av basisklassen arves, men tilgangsmodifikatorer påvirker synligheten i den avledede klassen. Access-modifikatorer inkluderer: public, protected, internalog private.

Offentlige medlemmer

Offentlige medlemmer er tilgjengelige fra alle koder som har tilgang til klassen. Avledede klasser arver offentlige medlemmer, og de er tilgjengelige utenfor klassehierarkiet.


public class BaseClass
{
    public int publicField;
    public void PublicMethod() { }
}

public class DerivedClass : BaseClass
{
    public void AccessPublicMember()
    {
        publicField = 10;
        PublicMethod();
    }
}

I dette eksemplet arver DerivedClasspublicField og PublicMethod medlemmer fra BaseClass. Den AccessPublicMember metoden i DerivedClass har tilgang til disse medlemmene. Offentlige medlemmer er også tilgjengelige fra kode som er utenfor klassehierarkiet.

Beskyttede medlemmer

Beskyttede medlemmer er tilgjengelige i klassen der de er deklarert og innenfor avledede klasser. De er ikke tilgjengelige utenfor klassehierarkiet.


public class BaseClass
{
    protected int protectedField;
    protected void ProtectedMethod() { }
}

public class DerivedClass : BaseClass

{
    public void AccessProtectedMember()
    {
        protectedField = 10;
        ProtectedMethod();
    }
}

I dette eksemplet arver DerivedClassprotectedField og ProtectedMethod medlemmer fra BaseClass. Den AccessProtectedMember metoden i DerivedClass har tilgang til disse medlemmene. Hvis du imidlertid prøver å få tilgang til beskyttede medlemmer utenfor klassehierarkiet, genereres det en kompileringstidsfeil.

Interne medlemmer

Interne medlemmer er tilgjengelige i samme samling. De er ikke tilgjengelige fra utenfor samlingen, selv om klassen er arvet.


public class BaseClass
{
    internal int internalField;
    internal void InternalMethod() { }
}

public class DerivedClass : BaseClass
{
    public void AccessInternalMember()
    {
        internalField = 10;
        InternalMethod();
    }
}

I dette eksemplet arver DerivedClassinternalField og InternalMethod medlemmer fra BaseClass. Den AccessInternalMember metoden i DerivedClass har tilgang til disse medlemmene fordi de er i samme samling. Hvis du imidlertid prøver å få tilgang til interne medlemmer utenfor samlingen, genereres det en kompileringstidsfeil.

Private medlemmer

Private medlemmer er bare tilgjengelige i klassen de er deklarert i. Avledede klasser arver ikke private medlemmer, så de er ikke direkte tilgjengelige i den avledede klassen.


public class BaseClass
{
    private int privateField;
    private void PrivateMethod() { }
}

public class DerivedClass : BaseClass
{
    public void AccessPrivateMember()
    {
        // Can't access privateField or PrivateMethod
    }
}

I dette eksemplet arver DerivedClass fra BaseClass, men den får ikke tilgang til privateField eller PrivateMethod medlemmer fordi de er private.

Undersøk bruken av abstrakte, virtuelle og forseglede nøkkelord i basisklassen

Grunnleggende og avledede klasser bruker abstract, virtualog sealed nøkkelord til å kontrollere virkemåten til medlemmer som arves. Med disse nøkkelordene kan du definere kontrollnivået som avledede klasser har over medlemmene i basisklassen.

Undersøk bruken av nøkkelordet abstract

Nøkkelordet abstract i C# brukes til å definere klasser og klassemedlemmer som er ufullstendige og må implementeres i avledede klasser. En abstrakt klasse kan ikke startes direkte og er ment å være en basisklasse for andre klasser. Abstrakte metoder og egenskaper deklareres uten implementering og må overstyres i ikke-sporede avledede klasser.

For eksempel:

public abstract class Shape
{
    public abstract int GetArea();
}

public class Square : Shape
{
    private int _side;

    public Square(int side)
    {
        _side = side;
    }

    public override int GetArea()
    {
        return _side * _side;
    }
}

class Program
{
    static void Main()
    {
        Square square = new Square(5);
        Console.WriteLine($"Area of the square = {square.GetArea()}");
    }
}

I dette eksemplet er Shape klassen abstrakt og inneholder en abstrakt metode GetArea. Klassen Square arver fra Shape og gir en implementering for GetArea-metoden. Klassen Square kan startes, og den GetArea metoden returnerer området på kvadratet.

Følgende regler beskriver hvordan abstract-nøkkelordet påvirker arv:

  • Abstrakte klasser: En abstrakt klasse kan ikke startes direkte. Den abstrakte klassen er en basisklasse for avledede klasser, og de avledede klassene må gi implementeringer for alle abstrakte medlemmer av den abstrakte klassen.
  • Abstrakte metoder: Abstrakte metoder deklareres uten implementering i den abstrakte klassen. Avledede klasser må overstyre disse metodene og gi implementeringen.
  • Abstrakte egenskaper: I likhet med abstrakte metoder deklareres abstrakte egenskaper uten implementering og må overstyres i avledede klasser.

Nøkkelordet abstract i C# er et kraftig verktøy for å definere ufullstendige klasser og medlemmer som må implementeres i avledede klasser. Den håndhever en kontrakt som avledede klasser må følge, slik at visse metoder og egenskaper implementeres. Riktig bruk av abstract nøkkelord fremmer en klar avgrenselse av ansvarsområder mellom grunnklasser og avledede klasser.

Undersøk bruken av nøkkelordet virtual

Nøkkelordet virtual i C# brukes til å definere metoder og egenskaper som kan overstyres i avledede klasser. En virtuell metode eller egenskap har en implementering i basisklassen, men den kan utvides eller endres i avledede klasser. Avledede klasser kan overstyre virtuelle medlemmer for å gi sine egne implementeringer.

For eksempel:


public class Animal
{
    public virtual void MakeSound()
    {
        Console.WriteLine("Animal makes a sound");
    }
}

public class Dog : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("Dog barks");
    }
}

class Program
{
    static void Main()
    {
        Animal animal = new Dog();
        animal.MakeSound();
    }
}

I dette eksemplet definerer Animal-klassen en virtuell metode MakeSound som skriver ut en generisk melding. Klassen Dog arver fra Animal og overstyrer MakeSound metoden for å skrive ut en bestemt melding. Når du oppretter et Dog objekt og kaller MakeSound metoden, utføres den overstyrte implementeringen i Dog-klassen.

Følgende regler beskriver hvordan virtual-nøkkelordet påvirker arv:

  • Virtuelle metoder: En virtuell metode har en implementering i basisklassen, men den kan overstyres i avledede klasser.
  • Virtuelle egenskaper: I likhet med virtuelle metoder har virtuelle egenskaper en implementering i basisklassen og kan overstyres i avledede klasser.

Undersøk bruken av nøkkelordet sealed

Det sealed nøkkelordet i C# brukes til å hindre at et klasse- eller klassemedlem arves eller overstyres. Når en klasse er merket som sealed, kan den ikke brukes som basisklasse for andre klasser. Når en metode er merket som sealed, kan den ikke overstyres i avledede klasser.

For eksempel:


public class BaseClass
{
    public virtual void Method1()
    {
        Console.WriteLine("Method1 in BaseClass");
    }

    public virtual void Method2()
    {
        Console.WriteLine("Method2 in BaseClass");
    }
}

public class DerivedClass : BaseClass
{
    public sealed override void Method1()
    {
        Console.WriteLine("Method1 in DerivedClass");
    }

    public override void Method2()
    {
        Console.WriteLine("Method2 in DerivedClass");
    }
}

public class FinalClass : DerivedClass
{
    // This class can't override Method1 because it's sealed in DerivedClass
    public override void Method2()
    {
        Console.WriteLine("Method2 in FinalClass");
    }
}

I dette eksemplet arver DerivedClass fra BaseClass og overstyrer Method1 metoden, og markerer den som sealed. Metoden Method2 overstyres også i DerivedClass men er ikke forseglet. FinalClass arver fra DerivedClass og prøver å overstyre Method2 metoden. Den kan imidlertid ikke overstyre Method1 metoden fordi den er forseglet i DerivedClass.

Følgende regler beskriver hvordan sealed-nøkkelordet påvirker arv:

  • Forseglede klasser: En forseglet klasse kan ikke brukes som basisklasse for andre klasser. Det hindrer arv fra den forseglede klassen.
  • Forseglede metoder: En forseglet metode kan ikke overstyres i avledede klasser. Det hindrer ytterligere endring av metoden i avledede klasser.
  • Forseglede egenskaper: I likhet med forseglede metoder kan ikke forseglede egenskaper overstyres i avledede klasser.

Forseglede klasser og metoder er nyttige når du vil hindre ytterligere utvidelse eller endring av en klasse eller metode. De gir en måte å begrense arv og sikre at enkelte medlemmer forblir uendret.

Undersøk implisitt arv fra objekt

I C#arver alle klasser implisitt fra Object klassen. Klassen Object definerer flere metoder som er tilgjengelige for alle klasser, for eksempel ToString, Equalsog GetHashCode. Hvis en klasse ikke eksplisitt arver fra en annen klasse, arver den fortsatt fra Object som standard.

  • ToString: Metoden ToString returnerer en streng som representerer gjeldende objekt. Som standard returnerer den det fullstendige navnet på klassen.
  • Equals: Metoden Equals sammenligner to objekter for likhet. Som standard sammenligner den referansene til objektene.
  • GetHashCode: Metoden GetHashCode returnerer en hash-kode for gjeldende objekt. Som standard returnerer den hash-koden for objektets referanse.

Vurder følgende kodeeksempel som oppretter tre Person objekter og demonstrerer de arvede metodene ToString, Equalsog GetHashCode:

Person person1 = new Person { Name = "Alice", Age = 30 };
Person person2 = new Person { Name = "Alice", Age = 30 };
Person person3 = person1;

Console.WriteLine(person1.ToString());
Console.WriteLine(person1.Equals(person2));
Console.WriteLine(person1.GetHashCode());
Console.WriteLine(person1.Equals(person3));

public class Person
{
    public string? Name { get; set; }
    public int Age { get; set; }
}

public class Employee : Person
{
    public int EmployeeNumber { get; set; }
    public decimal Salary { get; set; }
}

// Output: Person
//         False
//         32854180
//         True

I dette kodeeksempelet returnerer ToString-metoden det fullstendige navnet på Person-klassen, som inkluderer det definerte navneområdet. Den første Equals metoden sammenligner referansene til person1 og person2 objekter og returnerer False. Metoden GetHashCode returnerer hash-koden for referansen til person1-objektet. Deretter sammenligner Equals-metoden referansene til person1 og person3 objekter og returnerer True.

Sammendrag

Arv gjør det mulig for avledede klasser å arve grunnleggende klassemedlemmer som definerer et felles sett med attributter og virkemåter. Avledede klasser kan utvide eller endre virkemåten til basisklassen ved å legge til nye medlemmer eller overstyre eksisterende medlemmer. Nøkkelordene abstract, virtualog sealed brukes til å kontrollere hvordan grunnleggende klassemedlemmer arves eller overstyres. Synligheten til arvede medlemmer påvirkes av tilgangsmodifikatorer, for eksempel public, protected, internalog private. Alle klasser i C# arver implisitt fra Object klassen, som inneholder flere metoder, for eksempel ToString, Equalsog GetHashCode, som er tilgjengelige for alle klasser.