Overstyre egenskaper og metoder i en avledet klasse
I C#kan du bruke nøkkelordet override til å utvide eller endre virkemåten til basisklassen i den avledede klassen. Med nøkkelordet override kan du overstyre egenskaper og metoder som arves fra basisklassen, og gi egendefinerte implementeringer i den avledede klassen. Dette gjør at du kan bruke kode som er definert i basisklassen på nytt, og utvide eller endre virkemåten til basisklassen i den avledede klassen.
Hvis du vil overstyre en egenskap eller metode i en avledet klasse, må du følge disse trinnene:
- Deklarer medlemmene i basisklassen som enten
abstractellervirtual. - Overstyr medlemmene i den avledede klassen.
- Du kan også bruke
base-nøkkelordet til å få tilgang til den grunnleggende klasseimplementeringen fra det overstyrte medlemmet i den avledede klassen.
Deklarer abstrakte og virtuelle medlemmer av basisklassen
Før du kan overstyre medlemmene i en avledet klasse, må du deklarere medlemmene i basisklassen som enten abstract eller virtual.
- Abstrakt: Nøkkelordet
abstractindikerer at medlemmet ikke har noen implementering og må overstyres i en avledet klasse. - Virtuell: Nøkkelordet
virtualindikerer at medlemmet har en implementering, men kan overstyres eller utvides i en avledet klasse.
Følgende eksempel viser hvordan du erklærer abstrakte og virtuelle medlemmer i en basisklasse:
public class BaseClass
{
public string Property1 { get; set; } = "Base - Property1";
public string Property2 { get; set; } = "Base - Property2";
public virtual void Method1()
{
Console.WriteLine("Base - Method1");
}
public void Method2()
{
Console.WriteLine("Base - Method2");
}
}
Overstyre medlemmer i den avledede klassen
Når du har deklarert medlemmene i basisklassen som enten abstract eller virtual, kan du overstyre medlemmene i den avledede klassen ved hjelp av nøkkelordet override. Nøkkelordet override indikerer at medlemmet i den avledede klassen overstyrer medlemmet i basisklassen.
Vurder følgende eksempel:
// Step 1: Create instances of the base class and the derived classes
BaseClass baseClass = new BaseClass();
DerivedClass derivedClass = new DerivedClass();
BaseClass baseClassReferencingDerivedClass = new DerivedClass();
// Step 2: Access properties and methods of the base class
Console.WriteLine($"\n{baseClass.Property1}");
Console.WriteLine($"{baseClass.Property2}");
baseClass.Method1();
baseClass.Method2();
// Step 3: Access properties and methods of the derived class
Console.WriteLine($"\n{derivedClass.Property1}");
Console.WriteLine($"{derivedClass.Property2}");
derivedClass.Method1();
derivedClass.Method2();
// Step 4: Access properties and methods of the base class that references the derived class
Console.WriteLine($"\n{baseClassReferencingDerivedClass.Property1}");
Console.WriteLine($"{baseClassReferencingDerivedClass.Property2}");
baseClassReferencingDerivedClass.Method1();
baseClassReferencingDerivedClass.Method2();
/*Output:
Base - Property1
Base - Property2
Base - Method1
Base - Method2
Derived - Property1
Derived - Property2
Derived - Method1
Derived - Method2
Derived - Property1
Base - Property2
Derived - Method1
Base - Method2
*/
public class BaseClass
{
public virtual string Property1 { get; set; } = "Base - Property1";
public virtual string Property2 { get; set; } = "Base - Property2";
public virtual void Method1()
{
Console.WriteLine("Base - Method1");
}
public void Method2()
{
Console.WriteLine("Base - Method2");
}
}
public class DerivedClass : BaseClass
{
public override string Property1 { get; set; } = "Derived - Property1";
public new string Property2 { get; set; } = "Derived - Property2";
public override void Method1()
{
Console.WriteLine("Derived - Method1");
}
public new void Method2()
{
Console.WriteLine("Derived - Method2");
}
}
Denne koden viser hvordan du endrer og skjuler egenskaper og metoder i en avledet klasse ved hjelp av override og new nøkkelord. Koden definerer en basisklasse (BaseClass) og en avledet klasse (DerivedClass) som arver fra basisklassen. Basisklassen har to egenskaper (Egenskap1 og Egenskap2) og to metoder (Metode1 og Metode2). Den avledede klassen overstyrer Egenskap1 og Metode1, og skjuler Egenskap2 og Metode2 ved hjelp av nøkkelordet new.
Her er en oversikt over koden:
I trinn 1 oppretter koden en forekomst av basisklassen (
baseClass), en forekomst av den avledede klassen (derivedClass) og en forekomst av den avledede klassen som det refereres til av en basisklassevariabel (baseClassReferencingDerivedClass). DenbaseClassReferencingDerivedClassforekomsten demonstrerer polymorfisme, der en basisklassereferanse peker til et avledet klasseobjekt.I trinn 2 får koden tilgang til og skriver ut egenskapene og metodene for den grunnleggende klasseforekomsten. Siden
baseClasser en forekomst avBaseClass, bruker den egenskapene og metodene som er definert iBaseClass. Utdataene viser verdiene og virkemåtene som definert i basisklassen.I trinn 3 får koden tilgang til og skriver ut egenskapene og metodene for den avledede klasseforekomsten. Siden
derivedClasser en forekomst avDerivedClass, bruker den de overstyrte egenskapene og metodene som er definert iDerivedClass. Utdataene gjenspeiler verdiene og virkemåtene som definert i den avledede klassen.I trinn 4 får koden tilgang til og skriver ut egenskapene og metodene til den avledede klasseforekomsten det refereres til av en basisklassevariabel. For egenskaper og metoder som overstyres (
Property1ogMethod1), brukes den avledede klasseimplementeringen. Men for egenskaper og metoder som er skjult (Property2ogMethod2), brukes den grunnleggende klasseimplementeringen. Dette demonstrerer forskjellen mellom overstyring av metode (ved hjelp avoverride) og metodes skjule (ved hjelp avnew).
Definere en abstrakt basisklasse
Når du definerer en basisklasse som abstract, angir du at klassen er ufullstendig og må implementeres av avledede klasser. Abstrakte klasser kan inneholde abstrakte egenskaper og metoder som må implementeres av avledede klasser. Abstrakte basisklasser kan ikke startes direkte, så de brukes som en mal for avledede klasser for å implementere de abstrakte medlemmene.
Vurder følgende eksempel:
// create instances of the base class and the derived classes
// Note: We can't create an instance of an abstract class
// BaseClass baseClass = new BaseClass(); // This line would cause a compile-time error
DerivedClass derivedClass = new DerivedClass();
BaseClass baseClassReferencingDerivedClass = new DerivedClass();
// access properties and methods of the derived class
Console.WriteLine($"\n{derivedClass.Property1}");
Console.WriteLine($"{derivedClass.Property2}");
derivedClass.Method1();
derivedClass.Method2();
// access properties and methods of the base class that references the derived class
Console.WriteLine($"\n{baseClassReferencingDerivedClass.Property1}");
Console.WriteLine($"{baseClassReferencingDerivedClass.Property2}");
baseClassReferencingDerivedClass.Method1();
baseClassReferencingDerivedClass.Method2();
/*Output:
Derived - Property1
Derived - Property2
Derived - Method1
Derived - Method2
Derived - Property1
Base - Property2
Derived - Method1
Base - Method2
*/
public abstract class BaseClass
{
public abstract string Property1 { get; set; }
public virtual string Property2 { get; set; } = "Base - Property2";
public abstract void Method1();
public void Method2()
{
Console.WriteLine("Base - Method2");
}
}
public class DerivedClass : BaseClass
{
public override string Property1 { get; set; } = "Derived - Property1";
public new string Property2 { get; set; } = "Derived - Property2";
public override void Method1()
{
Console.WriteLine("Derived - Method1");
}
public new void Method2()
{
Console.WriteLine("Derived - Method2");
}
}
Legg merke til at når basisklassen deklareres ved hjelp av nøkkelordet abstract, kan ikke basisklassen startes direkte. I stedet må du opprette forekomster av de avledede klassene som implementerer de abstrakte medlemmene. Den avledede klassen må gi implementeringer for de abstrakte medlemmene som er definert i basisklassen. Medlemmer som ikke er abstrakte, kan overstyres eller skjules i den avledede klassen.
Overstyr implisitt arvet medlemmer av Objekt-klassen
Alle klasser i C# arver implisitt fra Object klassen. Klassen Object definerer flere medlemmer som arves av alle klasser, for eksempel ToString, Equalsog GetHashCode. Du kan overstyre disse medlemmene i klassene for å gi egendefinerte implementeringer.
Vurder følgende eksempel:
// create instances of the derived classes
DerivedClass1 derivedClass1 = new DerivedClass1();
DerivedClass2 derivedClass2a = new DerivedClass2 { Property1 = "Value1", Property2 = "Value2" };
DerivedClass2 derivedClass2b = new DerivedClass2 { Property1 = "Value1", Property2 = "Value2" };
DerivedClass2 derivedClass2c = new DerivedClass2 { Property1 = "Value3", Property2 = "Value4" };
// demonstrate Object class methods for DerivedClass1
Console.WriteLine("\nDemonstrating Object class methods for DerivedClass1:");
Console.WriteLine($"ToString: {derivedClass1.ToString()}");
Console.WriteLine($"Equals: {derivedClass1.Equals(new DerivedClass1())}");
Console.WriteLine($"GetHashCode: {derivedClass1.GetHashCode()}");
// demonstrate overridden Object class methods for DerivedClass2
Console.WriteLine("\nDemonstrating overridden Object class methods for DerivedClass2:");
Console.WriteLine($"ToString: {derivedClass2a.ToString()}");
Console.WriteLine($"Equals (derivedClass2a vs derivedClass2b): {derivedClass2a.Equals(derivedClass2b)}"); // should return true
Console.WriteLine($"Equals (derivedClass2a vs derivedClass2c): {derivedClass2a.Equals(derivedClass2c)}"); // should return false
Console.WriteLine($"GetHashCode (derivedClass2a): {derivedClass2a.GetHashCode()}");
Console.WriteLine($"GetHashCode (derivedClass2b): {derivedClass2b.GetHashCode()}");
Console.WriteLine($"GetHashCode (derivedClass2c): {derivedClass2c.GetHashCode()}");
/*Output:
Demonstrating Object class methods for DerivedClass1:
ToString: DerivedClass1
Equals: False
GetHashCode: [HashCode]
Demonstrating overridden Object class methods for DerivedClass2:
ToString: DerivedClass2: Property1 = Value1, Property2 = Value2
Equals (derivedClass2a vs derivedClass2b): True
Equals (derivedClass2a vs derivedClass2c): False
GetHashCode (derivedClass2a): [HashCode]
GetHashCode (derivedClass2b): [HashCode]
GetHashCode (derivedClass2c): [HashCode]
*/
public abstract class BaseClass
{
public abstract string Property1 { get; set; }
public virtual string Property2 { get; set; } = "Base - Property2";
public abstract void Method1();
public void Method2()
{
Console.WriteLine("Base - Method2");
}
}
public class DerivedClass1 : BaseClass
{
public override string Property1 { get; set; } = "Derived1 - Property1";
public new string Property2 { get; set; } = "Derived1 - Property2";
public override void Method1()
{
Console.WriteLine("Derived1 - Method1");
}
public new void Method2()
{
Console.WriteLine("Derived1 - Method2");
}
}
public class DerivedClass2 : BaseClass
{
public override string Property1 { get; set; } = "Derived2 - Property1";
public new string Property2 { get; set; } = "Derived2 - Property2";
public override void Method1()
{
Console.WriteLine("Derived2 - Method1");
}
public new void Method2()
{
Console.WriteLine("Derived2 - Method2");
}
// Override ToString method
public override string ToString()
{
return $"DerivedClass2: Property1 = {Property1}, Property2 = {Property2}";
}
// Override Equals method
public override bool Equals(object obj)
{
if (obj is DerivedClass2 other)
{
return Property1 == other.Property1 && Property2 == other.Property2;
}
return false;
}
// Override GetHashCode method
public override int GetHashCode()
{
return HashCode.Combine(Property1, Property2);
}
}
I dette eksemplet arver klassene DerivedClass1 og DerivedClass2 fra BaseClass klassen. Klassen DerivedClass2 overstyrer metodene ToString, Equalsog GetHashCode arvet fra Object klassen. Metoden ToString returnerer en strengrepresentasjon av objektet, Equals-metoden sammenligner to objekter for likhet, og GetHashCode-metoden returnerer en hash-kode for objektet. Klassen DerivedClass2 gir egendefinerte implementeringer for disse metodene for å vise egenskapene til objektet og sammenligne objekter basert på egenskapene.
Sammendrag
Hvis du overstyrer egenskaper og metoder i en avledet klasse, kan du utvide eller endre virkemåten til basisklassen. Ved å bruke nøkkelordet override kan du angi egendefinerte implementeringer for egenskaper og metoder som er arvet fra basisklassen. Dette gjør at du kan bruke kode som er definert i basisklassen på nytt, og utvide eller endre virkemåten til basisklassen i den avledede klassen. Du kan også bruke nøkkelordet new til å skjule egenskaper og metoder i basisklassen og gi nye implementeringer i den avledede klassen.