Utforsk arvebasert polymorfisme
Arvebasert polymorfisme er basert på et klassehierarki der avledede klasser arver atferd og egenskaper fra en basisklasse. Arverelasjonen gjør det mulig å behandle objekter av avledede klasser som objekter i basisklassen. Hvis du vil kunne behandle avledede klasseobjekter som baseklasseobjekter, kan du skrive kode som fungerer med flere typer objekter uten å vite den bestemte typen på kompileringstidspunktet.
Følgende kodeeksempel demonstrerer arvebasert polymorfisme i C#:
// Base class
public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("The animal makes a sound.");
}
}
// Derived class Dog
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("The dog barks.");
}
}
// Derived class Cat
public class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine("The cat meows.");
}
}
// Derived class Cow
public class Cow : Animal
{
public override void MakeSound()
{
Console.WriteLine("The cow moos.");
}
}
class Program
{
static void Main()
{
// Create an array of Animal objects
Animal[] animals = new Animal[3];
Animal animal1 = new Dog();
Animal animal2 = new Cat();
Animal animal3 = new Cow();
animals[0] = animal1;
animals[1] = animal2;
animals[2] = animal3;
// Demonstrate polymorphism
foreach (Animal animal in animals)
{
animal.MakeSound();
}
}
}
Legg merke til at Program-klassen oppretter en matrise med Animal objekter i denne eksempelkoden, og tilordner forekomster av Dog, Catog Cow til matriseelementene. Den MakeSound metoden kalles på hvert objekt i matrisen, som demonstrerer polymorfisme. Den MakeSound metoden overstyres i de avledede klassene for å gi spesifikk atferd for hver dyretype.
Kast et objekt av en basisklasse til en avledet klasse
Støping i C# er prosessen med å konvertere et objekt av én type til en annen type. Støping brukes ofte når du implementerer polymorfisme ved hjelp av arvhierarkier, der du har en basisklasse og én eller flere avledede klasser.
Det finnes to hovedtyper av casting:
Implisitt avstøpning: Dette skjer automatisk når du konverterer en avledet klasse til en basisklasse. Det er trygt fordi hver forekomst av en avledet klasse også er en forekomst av basisklassen.
BankAccount account = new CheckingAccount();Eksplisitt avstøpning: Dette krever en cast-operator og brukes når du konverterer en basisklasse til en avledet klasse. Det er ikke alltid trygt fordi ikke alle forekomster av en basisklasse er en forekomst av den avledede klassen.
CheckingAccount checkingAccount = (CheckingAccount)account;
Kast objekter ved hjelp av is og as nøkkelord
I C#kan du kaste objekter ved hjelp av is nøkkelordene og as . Disse nøkkelordene gir en sikker måte å kontrollere typen objekter på, før du sender det til en annen type. Her er noen vanlige måter å kaste objekter på i C#:
Bruke nøkkelordet
ismed mønstersamsvar:if (account is CheckingAccount checkingAccount) { // Use checkingAccount as a CheckingAccount }- Denne syntaksen kontrollerer om
accounter av typenCheckingAccount. - Hvis kontrollen er vellykket,
accountdenCheckingAccountog tilordner den til variabelencheckingAccount. - Denne tilnærmingen er konsis og sikker, da den kombinerer typekontrollen og kastet i ett trinn.
- Denne syntaksen kontrollerer om
Bruke
isnøkkelord etterfulgt av eksplisitt avstøpning:if (account is CheckingAccount) { CheckingAccount checkingAccount = (CheckingAccount)account; // Use checkingAccount as a CheckingAccount }- Denne syntaksen kontrollerer om
accounter av typenCheckingAccount. - Hvis kontrollen er vellykket,
accountden eksplisittCheckingAccountog tilordner den til variabelencheckingAccount. - Denne fremgangsmåten er mer detaljert enn mønsteret som samsvarer med syntaksen, men gir mer kontroll over støpeprosessen.
- Denne syntaksen kontrollerer om
Bruke nøkkelordet
as:CheckingAccount checkingAccount = account as CheckingAccount; if (checkingAccount != null) { // Use checkingAccount as a CheckingAccount }- Denne syntaksen forsøker å gi
accountCheckingAccountog tilordner resultatet tilcheckingAccount. - Hvis avstøpning er vellykket,
checkingAccountinneholder det støpte objektet. Ellers er det null. - Denne fremgangsmåten er nyttig når du vil kontrollere avstøpningsresultatet før du bruker det støpte objektet. Når du for eksempel vil unngå unntak og håndtere feiltilfellet på en grasiøs måte.
- Denne syntaksen forsøker å gi
Når du implementerer casting, bør du vurdere følgende retningslinjer:
- Bruke mønstersamsvar med
is: Kombinerer typekontroll og kast i ett trinn. - Bruk
isnøkkelord med eksplisitt avstøpning: Skiller typekontroll og kastes i to trinn, noe som gir mer kontroll over castingprosessen. - Bruke nøkkelordet
as: Forsøk på å kaste og håndtere feil på en grasiøs måte ved å returnere null.
- Bruke mønstersamsvar med
Å forstå disse støpeteknikkene er avgjørende for å arbeide med polymorfisme og arv i C#.
Unngå vanlige fallgruver når du implementerer polymorfisme
Når målet ditt er arvebasert polymorfisme, her er noen ting å unngå og noen ting å sikre:
Unngå å bruke forseglede klasser og metoder: Forseglede klasser og metoder kan ikke arves eller overstyres, noe som begrenser evnen til å bruke polymorfisme. Hvis du forsegler en klasse eller metode, forhindrer du ytterligere utvidelse og tilpassing. For eksempel:
public sealed class BankAccount { } // This class can't be inheritedUnngå overbruk av statiske metoder. Statiske metoder tilhører selve klassen i stedet for en forekomst av klassen. De kan ikke overstyres, noe som betyr at de ikke deltar i polymorfisme.
public static void PrintMessage() { } // This method can't be overriddenUnngå tett kobling. Tett kobling oppstår når klasser eller komponenter i et system er svært avhengige av hverandre. Dette betyr at endringer i én klasse direkte kan påvirke andre klasser, noe som gjør systemet mindre fleksibelt og vanskeligere å vedlikeholde. Tett kobling kan føre til vanskeligheter med testing, utvidelse og endring av koden.
public class BankAccount { public void TransferFunds(SavingsAccount savingsAccount) { // Tight coupling with SavingsAccount } }Unngå å bruke det nye nøkkelordet uten en god grunn. Det nye nøkkelordet skjuler basisklassemetoden i den avledede klassen, noe som kan føre til forvirring og uventet virkemåte. Bruk bare det nye nøkkelordet når du har tenkt å skjule basisklassemetoden med hensikt.
public class Dog : Animal { public new void MakeSound() // Hides the base class method. Better to use 'override' { Console.WriteLine("The dog barks."); } }Sikre konsekvente metodesignaturer. Kontroller at overstyrte metoder i avledede klasser har samme signatur som basisklassemetoden. Hvis du endrer metodesignaturen, skjules metoden i stedet for å overstyres.
public class Animal { public virtual void MakeSound(string sound) { Console.WriteLine("The animal makes a sound."); } } public class Dog : Animal { // Method signature doesn't match the base class public override void MakeSound() { Console.WriteLine("The dog barks."); } }
Sammendrag
Arvebasert polymorfisme i C# lar deg opprette et hierarki av klasser der avledede klasser arver atferd og egenskaper fra en basisklasse. Med denne arvemekanismen kan du behandle objekter av avledede klasser som objekter i basisklassen. Muligheten til å behandle avledede klasseobjekter som medlemmer av en basisklasse lar deg skrive kode som fungerer med flere typer objekter uten å vite den bestemte typen på kompileringstidspunktet. Ved å forstå støpingsteknikker, unngå vanlige fallgruver og følge anbefalte fremgangsmåter, kan du effektivt implementere polymorfisme i C#-programmene dine.