4032 Mer intro arv - Animal
Lärandemål
- Förstå innebörden av statisk (tidig, vid kompilering) och dynamisk (sen, vid köring) bindning, samt hur det påverkar kodens utseende.
- Kunna använda nyckelorden
virtual
ochoverride
på avsett vis.
Introduktion
Detta exempel är en fortsättning på föregående exempel. I det här exemplet görs några förändringar i klasserna Animal
, Cat
, Cow
och Dog
. Övriga klasser är oförändrade.
Klassen Animal
Metoden Act
markeras med virtual
för att den ska kunna ersättas i en ärvande klass.
using System;
namespace Animal
{
class Animal
{
protected int age;
public Animal()
{
age = 1;
}
public virtual void Act()
{
Console.WriteLine("hej hej");
}
}
}
Klassen Cat
Metoden Act
markeras med override
för att berätta att denna metod ersätter metoden med samma namn i superklassen.
using System;
namespace Animal
{
class Cat : Animal
{
//konstruktor
public Cat(int anAge)
{
age = anAge;
}
public override void Act()
{
Console.WriteLine("mjau mjau");
}
}
}
Klasserna Cow och Dog
På samma sätt som Cat
.
using System;
namespace Animal
{
class Cow : Animal
{
//konstruktor
public Cow(int anAge)
{
age = anAge;
}
public override void Act()
{
Console.WriteLine("mu muu");
}
}
}
using System;
namespace Animal
{
class Dog : Animal
{
//konstruktor
public Dog(int anAge)
{
age = anAge;
}
public override void Act()
{
Console.WriteLine("vov vov");
}
}
}
Klassen Zoo
Koden är oförändrad.
using System;
using System.Collections.Generic;
using System.Text;
namespace Animal
{
class Zoo
{
private List<Animal> animals;
public Zoo()
{
animals = new List<Animal>();
}
public void Add(Animal anAnimal)
{
animals.Add(anAnimal);
}
public void Run()
{
foreach (Animal djuret in animals)
{
djuret.Act();
}
}
}
}
Klassen Program med metoden Main
Koden i klassen är oförändrad.
using System;
namespace Animal
{
class Program
{
static void Main(string[] args)
{
Zoo zoo = new Zoo();
zoo.Add(new Cat(3));
zoo.Add(new Cat(1));
zoo.Add(new Cat(3));
zoo.Add(new Dog(4));
zoo.Add(new Dog(12));
zoo.Add(new Cow(7));
zoo.Add(new Cow(7));
zoo.Add(new Cow(7));
zoo.Run();
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
Körning av programmet ger utskriften:
mjau mjau
mjau mjau
mjau mjau
vov vov
vov vov
mu muu
mu muu
mu muu
Förklaring djuret.Act()
Nu kräver anropet
zoo.Run();
en förklaring. I metoden Run
körs följande foreach-sling.
foreach (Animal djuret in animals)
{
djuret.Act();
}
Första varvet i slingan är djuret
ett objekt av klassen Cat
. När koden körs anropar den metod Act
som finns i klassen Cat
. Detta kallas för dynamisk bindning. Det finns lite mer att berätta men vi sparar det till lite längre ner på sidan.
När koden kompileras har djuret
i foreach-slingan datatypen Animal
. Därför måste det finnas en metod Act
i klassen Animal
. Detta kallas statisk bindning.
Föregående exempel
Efter den senaste förklaringen kräver även föregående exempel en förklaring. Där fanns det ingen metod Act
i klasserne Cat
, Cow
och Dog
.
Statisk bindning
När koden kompileras godkänns foreach-slingan av samma anledning som ovan. Vi kan alltså inte ta bort metoden Act
i klassen Animal
. Då kompilerar inte foreach-slingan.
Dynamisk bindning
När första varvet i foreach-slingan körs innehåller djuret
ett objekt av klassen Cat
. Eftersom metoden Act
inte finns implementerad i klassen Cat
så letar datorn efter samma metod i överklassen Animal
. Där finns metoden Act
. Det är denna metod som körs.