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
- Skapa basklassen
Vehicle. - Skapa subklasserna
CarochBike. - Låt båda skriva över
drive(). - Skapa en lista med både bilar och cyklar.
- 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.