Presentationer Slide 1/1

Kap 3.6

Arv och polymorfism

Vi bygger vidare på klasser och låter samma metodnamn ge olika beteende.

Mål

Efter lektionen ska du kunna...

  • förklara vad arv innebär
  • skapa en subklass som ärver från en basklass
  • förklara override
  • förklara polymorfism
  • använda super() i enkla exempel

Viktigt

Använd arv när det passar

Arv passar när relationen betyder är en.

En hund är ett djur.

En rektangel är en form.

En bil är inte en motor. En bil har en motor.

Begrepp

Orden du behöver

  • basklass: klassen som andra ärver från
  • subklass: klassen som bygger vidare
  • arv: subklassen får metoder från basklassen
  • override: subklassen skriver egen version av en metod
  • polymorfism: samma metodanrop kan ge olika resultat

Arv

Dog ärver från Animal

class Animal:
    def breathe(self):
        print("Djuret andas.")

class Dog(Animal):
    def wag_tail(self):
        print("Hunden viftar på svansen.")

Dog(Animal) betyder att Dog ärver från Animal.

Arv

Ärvd metod kan användas

dog = Dog()
dog.breathe()
dog.wag_tail()
Djuret andas.
Hunden viftar på svansen.

Dog har ingen egen breathe(), men ärver den.

UML

Arv i klassdiagram

classDiagram
    direction BT
    Dog --> Animal : inherits

    class Animal {
        +breathe()
    }

    class Dog {
        +wag_tail()
    }

Basklass

Det gemensamma ligger högre upp

class Animal:
    def speak(self):
        print("Djuret låter.")

Animal är den allmänna modellen.

Subklasser kan använda eller ändra det som finns där.

Subklass

Subklassen bygger vidare

class Dog(Animal):
    def wag_tail(self):
        print("Hunden viftar på svansen.")

Dog får metoder från Animal.

Dog kan också ha egna metoder.

Override

Subklassen skriver om metoden

class Animal:
    def speak(self):
        print("Djuret låter.")

class Dog(Animal):
    def speak(self):
        print("Hunden säger voff.")

Dog har en egen version av speak().

Override

Vilken metod körs?

animal = Animal()
dog = Dog()

animal.speak()
dog.speak()
Djuret låter.
Hunden säger voff.

Polymorfism

Samma anrop, olika resultat

animals = [Dog(), Cat(), Bird()]

for animal in animals:
    animal.speak()

Loopen behöver inte veta exakt vilken klass objektet har.

Den kör bara animal.speak().

UML

Polymorfism i klassdiagram

classDiagram
    direction BT
    Dog --> Animal : inherits
    Cat --> Animal : inherits
    Bird --> Animal : inherits

    class Animal {
        +speak()
    }

    class Dog {
        +speak()
    }

    class Cat {
        +speak()
    }

    class Bird {
        +speak()
    }

Skillnad

Override och polymorfism

Override: en subklass skriver en egen version av en metod.

Polymorfism: samma metodanrop fungerar på flera olika objekt.

Override gör ofta polymorfism möjlig, men orden betyder inte samma sak.

Override

Override utan polymorfism

dog = Dog()
dog.speak()

Dog har fortfarande skrivit om speak().

Det är override.

Men här behandlas inte flera olika objekt på samma sätt.

Polymorfism

Polymorfism utan arv

class Dog:
    def speak(self):
        print("Voff")

class Robot:
    def speak(self):
        print("Beep")

things = [Dog(), Robot()]

Dog och Robot ärver inte från samma klass.

Polymorfism

Samma metodnamn räcker i Python

for thing in things:
    thing.speak()
Voff
Beep

Samma rad fungerar eftersom båda objekten har speak().

Former

Polymorfism med area

shapes = [Rectangle(4, 5), Circle(3)]

for shape in shapes:
    print("Area:", shape.area())

Alla objekt har area().

Men varje klass räknar på sitt eget sätt.

UML

Shape, Rectangle och Circle

classDiagram
    direction BT
    Rectangle --> Shape : inherits
    Circle --> Shape : inherits

    class Shape {
        +area()
    }

    class Rectangle {
        -width
        -height
        +area()
    }

    class Circle {
        -radius
        +area()
    }

super()

Återanvänd basklassens kod

class Student(Person):
    def __init__(self, name, school):
        super().__init__(name)
        self.school = school

super().__init__(name) kör basklassens konstruktor.

Subklassen lägger bara till det som är nytt.

UML

Person och Student

classDiagram
    direction BT
    Student --> Person : inherits

    class Person {
        +name
        +introduce()
    }

    class Student {
        +school
        +introduce()
    }

Öva

kap3-6-vehicles.py

  1. Skapa basklassen Vehicle.
  2. Skapa subklasserna Car och Bike.
  3. Låt båda skriva över drive().
  4. Skapa en lista med både bilar och cyklar.
  5. Kör vehicle.drive() i en loop.

Sammanfattning

Kom ihåg

  • Arv återanvänder kod från en basklass.
  • Subklasser kan lägga till egna metoder.
  • Override ändrar en ärvd metod.
  • Polymorfism gör att samma metodanrop kan ge olika beteende.
  • super() återanvänder basklassens logik.