Undersøk prinsippene for klassearv
Arv er en av de viktigste egenskapene til objektorientert programmering. Den lar deg opprette et hierarki av klasser ved å definere relasjoner mellom klasser. I C#kan du opprette en basisklasse som definerer vanlig virkemåte og egenskaper, og deretter opprette avledede klasser som arver og utvider denne virkemåten.
En basisklasse med navnet Person kan for eksempel definere Name og Age egenskaper. En avledet klasse med navnet Employee kan arve disse egenskapene og definere andre egenskaper, for eksempel EmployeeNumber og Salary.
Dette eksemplet kan representeres ved hjelp av følgende C#-kode:
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; }
}
Dette kodeeksempelet definerer Person klassen og deretter Employee klassen. Legg merke til kolon (:) tegnet i Employee klassedeklarasjon. Kolonet (:) mellom Employee og Person angir at Employee klassen arver fra Person klassen. I dette tilfellet arver Employee klassen egenskapene Name og Age og definerer to egenskaper til: EmployeeNumber og Salary. Når et Employee objekt opprettes, har det tilgang til Name og Age egenskaper som er definert i Person-klassen, i tillegg til egenskapene EmployeeNumber og Salary definert i Employee klassen. Når et Person objekt opprettes, har det bare tilgang til egenskapene Name og Age.
Med arv kan du opprette et hierarki av klasser som deler felles atferd og egenskaper. Den gjør det mulig å bruke kode på nytt og definere relasjoner mellom klasser. Ved hjelp av arv kan du opprette mer vedlikeholdbar og utvidbar kode.
Fordeler med arv
Arv gir flere fordeler, inkludert:
- Gjenbruk av kode: Arv lar deg bruke kode som er definert i en basisklasse i en avledet klasse på nytt. Dette reduserer duplisering og fremmer gjenbruk av kode.
- Extensibility: Arv gjør det mulig å utvide virkemåten til en basisklasse ved å legge til nye medlemmer i en avledet klasse. Du kan definere nye egenskaper, metoder og hendelser i en avledet klasse.
- Encapsulation: Arv fremmer innkapsling ved å la deg skjule implementeringsdetaljene for en basisklasse fra en avledet klasse. Arv og innkapsling gjør det mulig å definere et klart grensesnitt for samhandling med objekter i en avledet klasse.
- konsekvens: Arv fremmer konsekvens ved å la deg definere vanlig virkemåte i en basisklasse. Arving fra en basisklasse sikrer at de avledede klassene deler samme grunnleggende virkemåte.
- polymorfisme: Arv muliggjør polymorfisme, som lar deg behandle objekter i en avledet klasse som objekter i deres basisklasse. Polymorfisme gjør det mulig å skrive kode som fungerer med objekter av forskjellige typer uten å vite den bestemte typen på kompileringstidspunktet.
Sammenligne klassearv med grensesnittimplementering
C# inneholder to mekanismer for å definere relasjoner mellom klasser: klassearv og implementering av grensesnitt. Klassearv gjør det mulig for en klasse å arve medlemmer fra en basisklasse, mens grensesnittimplementering gjør det mulig for en klasse å implementere medlemmer som er definert i et grensesnitt. Begge mekanismene aktiverer gjenbruk av kode og fremmer polymorfisme, men de har forskjellige egenskaper:
Klassearv har følgende egenskaper:
- En klasse kan arve fra bare én basisklasse.
- En avledet klasse kan bruke på nytt, utvide og endre virkemåten som er definert i basisklassen.
- Arv oppretter en «is-a»-relasjon mellom klasser.
Grensesnittimplementering har følgende egenskaper:
- En klasse kan implementere flere grensesnitt.
- En klasse kan definere sin egen virkemåte og implementere medlemmene som er definert i et grensesnitt.
- Grensesnittimplementering oppretter en «can-do»-relasjon mellom klasser.
Forskjellen mellom "is-a" og "can-do"-relasjoner er viktig når du utformer objektorienterte systemer. Generelt bør du bruke klassearv når en avledet klasse er en spesialisert versjon av en basisklasse. Du bør bruke grensesnittimplementering når en klasse kan utføre et bestemt sett med handlinger.
Et eksempel på når du skal bruke klassearv er når du har en basisklasse kalt Dog og avledede klasser med navnet German Shepherd og Golden Retriever.
German Shepherd og Golden Retriever er spesialiserte versjoner av en Dog. I dette tilfellet kan du bruke klassearv til å definere et felles sett med egenskaper og metoder i Dog-klassen, og deretter utvide og endre denne virkemåten i German Shepherd og Golden Retriever klasser.
Et eksempel på når du skal bruke grensesnittimplementering er når du har et grensesnitt kalt IDrawable som definerer en Draw metode. Du kan implementere IDrawable-grensesnittet i klasser som kan tegnes, for eksempel Circle og Rectangle. I dette tilfellet kan du bruke grensesnittimplementering til å definere et felles sett med handlinger som deles av ulike klasser.
Sammenlign klassearv med polymorfisme
Klassearv og polymorfisme er nært beslektede begreper i objektorientert programmering. Arv lar deg definere et hierarki av klasser som deler vanlig atferd, mens polymorfisme lar deg behandle objekter i en avledet klasse som objekter i deres basisklasse.
Vurder for eksempel en basisklasse med navnet HousePet og avledede klasser med navnet Dog og Cat. Klassen HousePet definerer en Speak metode som returnerer en streng som representerer lyden kjæledyret lager. Klassen Dog overstyrer Speak metoden for å returnere «Woof», og Cat klassen overstyrer Speak metoden for å returnere «Meow». Du kan opprette et HousePet objekt med navnet myPet av typen Dog eller Cat og ringe Speak metoden for å få riktig svar.
I dette eksemplet definerer HousePet-klassen en vanlig Speak virkemåte som Dog og Cat klasser deler. Klassene Dog og Cat overstyrer Speak metoden for å tilpasse virkemåten. Når du kaller Speak metoden på et HousePet objekt som refererer til en av de avledede klassene, får du riktig svar basert på objekttypen. Her er kodeeksempelet som demonstrerer dette konseptet:
HousePet myPet1 = new Dog(); // Create a HousePet object named myPet1 that's of type Dog
HousePet myPet2 = new Cat(); // Create a HousePet object named myPet2 that's of type Cat
Console.WriteLine(myPet1.Speak()); // Call the Speak method on myPet1
Console.WriteLine(myPet2.Speak()); // Call the Speak method on myPet2
// Output: Woof
// Meow
public class HousePet
{
public virtual string Speak()
{
return "Hello";
}
}
public class Dog : HousePet
{
public override string Speak()
{
return "Woof";
}
}
public class Cat : HousePet
{
public override string Speak()
{
return "Meow";
}
}
Polymorfisme lar deg skrive kode som fungerer med objekter av forskjellige typer uten å vite deres spesifikke type på kompileringstidspunktet. I dette eksemplet oppnås polymorfisme ved å opprette forekomster av HousePet klassen som er av typen Dog eller Cat. Metoden Speak kalles på HousePet objekter, og det riktige svaret returneres basert på typen objekt, enten «Woof» eller «Meow». I C#kan polymorfisme oppnås ved hjelp av enten klassearv eller grensesnittimplementering.
Sammendrag
Arv er et grunnleggende konsept i objektorientert programmering som lar deg opprette et hierarki av klasser ved å definere relasjoner mellom klasser. I C#kan du bruke klassearv til å opprette en basisklasse som definerer vanlig virkemåte og egenskaper, og deretter opprette avledede klasser som arver og utvider denne virkemåten. Arv gir flere fordeler, inkludert gjenbruk av kode, utvidbarhet, innkapsling, konsistens og polymorfisme. Ved hjelp av arv kan du opprette mer vedlikeholdbar og utvidbar kode.