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
virtualochoverridepå 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.
Objektdiagram
