Utforsk arvebasert polymorfisme

Fullført

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 is med mønstersamsvar:

    
    if (account is CheckingAccount checkingAccount)
    {
        // Use checkingAccount as a CheckingAccount
    }
    
    
    • Denne syntaksen kontrollerer om account er av typen CheckingAccount.
    • Hvis kontrollen er vellykket, account den CheckingAccount og tilordner den til variabelen checkingAccount.
    • Denne tilnærmingen er konsis og sikker, da den kombinerer typekontrollen og kastet i ett trinn.
  • Bruke is nøkkelord etterfulgt av eksplisitt avstøpning:

    
    if (account is CheckingAccount)
    {
        CheckingAccount checkingAccount = (CheckingAccount)account;
        // Use checkingAccount as a CheckingAccount
    }
    
    
    • Denne syntaksen kontrollerer om account er av typen CheckingAccount.
    • Hvis kontrollen er vellykket, account den eksplisitt CheckingAccount og tilordner den til variabelen checkingAccount.
    • Denne fremgangsmåten er mer detaljert enn mønsteret som samsvarer med syntaksen, men gir mer kontroll over støpeprosessen.
  • Bruke nøkkelordet as:

    
    CheckingAccount checkingAccount = account as CheckingAccount;
    
    if (checkingAccount != null)
    {
        // Use checkingAccount as a CheckingAccount
    }
    
    
    • Denne syntaksen forsøker å gi accountCheckingAccount og tilordner resultatet til checkingAccount.
    • Hvis avstøpning er vellykket, checkingAccount inneholder 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.
  • 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 is nø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.

Å 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 inherited
    
    
  • Unngå 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 overridden
    
    
  • Unngå 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.