Arv i Python

Arv är ett kraftfullt sätt att återanvända kod från redan existerande klasser.

Varför Arv?

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.

Hur använder man arv i Python? – Exempel

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
Bakåt    |    Framåt