Arv är ett kraftfullt sätt att återanvända kod från redan existerande klasser.
Många gånger vill man återanvända kod från klasser man redan har programmerat. Istället för att programmera liknande klasser flera gånger, kan man ärva kod från en annan klass. En klass som ärver kod kallas för subklass och dess förälder för superklass. Det som är smidigt med arv är att subklassen får samma uppsättning av instansvariabler och metoder som superklassen, men det är även möjligt att lägga till nya metoder och klassvariabler om så önskas, som enbart är tillgängliga för subklassen.
För att visa hur arv i Python fungerar, ska vi programmera ett par fordon. Klassen vehicle (fordon), är superklassen och med hjälp av denna kan vi ärva fordonets egenskaper för att programmera subklasser, exempelvis en båt och en bil. Först bestämmer vi att alla fordon ska ha en färg, årsmodell samt en boolean som säger om fordonet är startad eller avstängd.
class Vehicle: def __init__(self, year, color): # Konstruktor self.year = year # Tilldelar år och färg till objektet self.color = color self.is_on = False # Boolean som avgör om fordonet är på eller av. False = av, True = på def start_vehicle(self): # En funktion som startar fordonet self.is_on = True def stop_vehicle(self): # En funktion som stänger av fordonet self.is_on = False
Vi har alltså skapat en superklass Vehicle som har en färg och en årsmodell. Klassen kan starta eller stängas av.
Vi skapar nu funktionen båt (boat):
class Boat(Vehicle): # Skapar klassen Boat. Vi anger att Boat ärver från Vehicle def __init__(self, year, color): # Konstruktor. Vi behöver year och color som inparametrar super().__init__(year, color) # Kalla på superklassen, och ange egenskaperna def sail(self): # Funktion som gör att båten kan segla print("Seglar")
Båten ärver alla egenskaper och funktioner från Vehicle, men får också funktionen att kunna segla.
På samma sätt skapar vi klassen bil (Car):
class Car(Vehicle): # Skapar klassen Car. Vi anger att Car ärver från Vehicle def __init__(self, year, color, brand): # Konstruktor. Vi behöver year, color och brand som inparametrar super().__init__(year, color) # Kalla på superklassen. Superklassen behöver year och color self.brand = brand # Car har i detta fall en extra egenskap, brand (modell) def drive(self): # Funktion som gör att bilen kör framåt print("Kör framåt")
Bilen ärver alla egenskaper från Vehicle och får dessutom funktionen att köra framåt och egenskapen brand (modell). Observera att klassen Boat och klassen Car är helt oberoende av varandra.
Vi skapar nu ett objekt av typen Boat och ett objekt av typen Car:
boat = Boat("2000", "röd") # Skapar ett objekt båt car = Car(2019, "vit", "XC60") # Skapar ett objekt bil
Vi kan nu anropa klasserna på vanligt vis:
car.drive() # Anropa att bilen ska köra boat.sail() # Anropa att båten ska segla
Kör framåt
Seglar
Men eftersom car och boat är helt fristående av varandra, kommer vi inte kunna anropa sail från car eller drive från boat:
car.sail() # Fungerar ej! En bil kan inte segla! boat.drive() # Fungerar ej! klassen båt har inte funktionen drive!
Vilket innebär att programmet kraschar.
Men start_vehicle och stop_vehicle var ju definierade i superklassen! Det innebär att båda subklasserna kan använda dessa funktioner:
car.start_vehicle() # Både klasserna har ärvt start_vehicle och stop_vehicle boat.stop_vehicle()
Vilket fungerar utmärkt!
På samma sätt är variablerna is_on och year definierade i superklassen. Alltså kan vi anropa dessa från båda subklasserna:
print(car.is_on) # Eftersom både klasserna har ärvt från superklassen, har både klasserna parametrarna is_on och year print(boat.year)
True
2000
Men parametern brand (modell) var ju en lokal inparameter vilket innebär att den bara är möjlig att kalla på från car:
print(car.brand) # Fungerar!
XC60
Men inte från boat:
print(boat.brand) # Och båt har inte egenskapen brand! Programmet kraschar