Leerpad
Een belangrijk onderdeel van moderne softwareontwikkeling is objectgeoriënteerd programmeren (OOP), waarmee programmeurs code gestructureerd, modulair en herbruikbaar kunnen organiseren. Abstracte klassen zijn één van de vele OOP-concepten die essentieel zijn om een sjabloon te creëren dat andere klassen kunnen gebruiken. In dit artikel leggen we uit wat abstracte klassen zijn, wat de voordelen zijn en hoe je Python's abc-module gebruikt om ze succesvol te bouwen.
Als je nieuw bent met Python, kun je met onze skill track leren werken met modules en packages, werken met ingebouwde datatypes en eigen functies schrijven.
Wat is een abstracte klasse?
Een abstracte klasse is als een sjabloon voor andere klassen. Ze definieert methoden die in elke klasse die ervan erft moeten worden opgenomen, maar levert niet de daadwerkelijke code voor die methoden.
Zie het als een recept zonder specifieke ingrediënten—het vertelt je welke stappen je moet volgen, maar de details hangen af van de subklasse.
Voorbeeld:
Stel dat je een programma bouwt om de oppervlakte van verschillende vormen te berekenen.
- Je maakt een abstracte klasse genaamd
Shapedie zegt dat elke vorm moet beschikken over eenarea()-methode. - Maar
Shapedefinieert niet hoearea()werkt—want de formule hangt af van het type vorm. - Elke specifieke vorm (zoals een
CircleofRectangle) erft vanShapeen levert zijn eigen versie vanarea().
Wil je meer leren over belangrijke Python-concepten? Schrijf je dan in voor onze cursus Intermediate Object-Oriented Programming in Python.
Waarom abstracte klassen gebruiken in Python?
Abstracte klassen zijn nuttig wanneer je wilt:
- Implementatie van methoden afdwingen: De methoden van een abstracte klasse fungeren als een contract, waardoor elke subklasse zijn eigen implementatie moet leveren. Dit verkleint de kans op inconsistente of ontbrekende implementaties door te garanderen dat specifieke functionaliteit aanwezig is in alle afgeleide klassen.
- Codehergebruik stimuleren: abstracte klassen kunnen zowel concrete als abstracte methoden bevatten. De concrete methoden verminderen code-duplicatie aanzienlijk en bevorderen het DRY-principe (Don't Repeat Yourself) door gedeelde functionaliteit te bieden die door alle subklassen kan worden geërfd.
- Leesbaarheid en onderhoudbaarheid verbeteren: Abstracte klassen helpen ontwikkelaars de structuur en functionaliteit van de software beter te begrijpen door een consistent en transparant raamwerk te bieden. Deze structuur maakt de code eenvoudiger te onderhouden door ontwerpprincipes als single responsibility en scheiding van verantwoordelijkheden af te dwingen.
- Polymorfisme bevorderen: Abstracte klassen maken het mogelijk om generieke code te schrijven die goed werkt met verschillende subklassen. Ontwikkelaars kunnen functies of methoden creëren die met elke subklasse van de abstracte klasse overweg kunnen; deze flexibiliteit verhoogt de uitbreidbaarheid van de code en de aanpasbaarheid aan toekomstige veranderingen.
Je kunt er bijvoorbeeld voor zorgen dat elke subklasse, zoals Dog of Cat, zijn eigen implementatie van de methode speak bevat als je een abstracte klasse Animal met een abstracte methode speak hebt. Die uniformiteit maakt je code betrouwbaar en voorspelbaar.
De abc-module in Python
De abc-module in Python biedt krachtige ingebouwde ondersteuning voor abstracte klassen. De module, die staat voor "Abstract Base Classes", geeft programmeurs de benodigde tools om abstracte klassen te maken, waaronder de decorator abstractmethod en de klasse ABC.
Door abstracte methoden te definiëren en hun implementatie in subklassen te vereisen, helpen deze tools je om uniformiteit en naleving van een vooraf gedefinieerde interface te behouden. Door de implementatie van essentiële methoden in alle afgeleide klassen te vereisen en de gedeeltelijke implementatie van gedeelde functionaliteit in abstracte basisklassen toe te staan, stimuleert de module ook betere ontwerppatronen.
Daarom is de ABC-module een cruciaal onderdeel voor het structureren van schaalbare, robuuste en stabiele Python-toepassingen.
Een abstracte klasse in Python maken
In de ABC-module worden twee essentiële componenten geïntroduceerd:
Abstract Base Class, oftewel ABC
De ABC-klasse is een ingebouwd onderdeel van Python dat dient als fundament voor het ontwikkelen van abstracte klassen. Je moet van ABC erven om een abstracte klasse te definiëren. Deze overerving geeft aan dat de klasse abstract is en niet direct kan worden geïnstantieerd. Door als blauwdruk te fungeren zorgen abstracte klassen ervoor dat elke concrete subklasse zich aan een set regels houdt.
Je kunt abstracte methoden binnen een abstracte klasse definiëren met de decorator abstractmethod. Abstracte methoden zijn placeholders die door elke concrete subklasse moeten worden geïmplementeerd en overschreven. Dit garandeert dat alle afgeleide klassen functionaliteit bieden voor de aangewezen methoden, wat de code consistent en voorspelbaar maakt. De decorator abstractmethod is een handig hulpmiddel om methoden te verplichten, terwijl subklassen flexibiliteit krijgen in hoe ze aan deze eisen voldoen.
Hier is een eenvoudig voorbeeld:
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14159 * self.radius ** 2
def perimeter(self):
return 2 * 3.14159 * self.radius
# Uncommenting the following line will raise an error because we’re missing method implementations
# shape = Shape() # TypeError: Can't instantiate abstract class Shape with abstract methods #area, perimeter
circle = Circle(5)
print(f"Area: {circle.area()}")
print(f"Perimeter: {circle.perimeter()}")
# Area: 78.53975
# Perimeter: 31.4159
Zoek je meer praktische Python-projecten? Bekijk dan onze lijst met de top 60 Python-projecten voor ontwikkelaars van elk niveau.
Hoe de abc-module de implementatie van methoden afdwingt
Dankzij de decorator abstractmethod is het gegarandeerd dat elke subklasse van een abstracte klasse de gemarkeerde methoden implementeert. Als voorzorgsmaatregel voorkomt dit dat subklassen worden gemaakt die niet over de vereiste mogelijkheden beschikken.
Python rapporteert een TypeError wanneer je probeert een subklasse te instantieren die niet alle abstracte methoden overschrijft. Deze strikte afdwinging verkleint de kans op bugs en verbetert de stabiliteit van de code door ontwikkelaars te helpen implementatiefouten vroeg te ontdekken.
Het garandeert ook dat alle concrete subklassen het beoogde gedrag en ontwerp van de abstracte klasse volgen.
Bijvoorbeeld:
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
# Missing area and perimeter implementation
# This will raise an error
rectangle = Rectangle(5, 10)
# TypeError: Can't instantiate abstract class Rectangle with abstract methods area, perimeter
Abstracte klassen en methoden in Python
In Python omvat het definiëren van een abstracte klasse het gebruik van de decorator abstractmethod en het erven van ABC. Zo kunnen programmeurs de basis leggen voor andere klassen door de methoden te definiëren die gebruikt moeten worden.
Hier is een grondige, stapsgewijze procedure:
- Importeer de benodigde modules: begin met het importeren van
ABCenabstractmethoduit deABC-module. Deze tools zijn nodig om abstracte klassen en methoden te definiëren. - Maak een klasse op basis van
ABC: maak een nieuwe klasse en laat deze erven vanABC. Deze overerving geeft aan dat de klasse abstract is en niet direct kan worden geïnstantieerd. - Definieer abstracte methoden met
@abstractmethod: gebruik de decorator@abstractmethodom te specificeren welke methoden subklassen moeten overschrijven. In essentie dienen deze methoden als placeholders, waardoor wordt gegarandeerd dat alle afgeleide klassen de vereiste bewerkingen uitvoeren.
Stapsgewijs voorbeeld van het definiëren van een abstracte klasse
Hier is een praktisch voorbeeld:
from abc import ABC, abstractmethod
class Vehicle(ABC):
@abstractmethod
def start_engine(self):
pass
@abstractmethod
def stop_engine(self):
pass
class Car(Vehicle):
def start_engine(self):
print("Car engine started")
def stop_engine(self):
print("Car engine stopped")
# Instantiating the abstract class directly will raise an error
# vehicle = Vehicle()
car = Car()
car.start_engine()
car.stop_engine()
# Car engine started
# Car engine stopped
Dit garandeert dat de functies start_engine en stop_engine worden geïmplementeerd door elke subklasse van Vehicle.
Praktisch voorbeeld: implementatie van een abstracte klasse
Kijk naar een uitgebreider voorbeeld met een Vehicle-klasse:
from abc import ABC, abstractmethod
class Vehicle(ABC):
def __init__(self, brand):
self.brand = brand
@abstractmethod
def start_engine(self):
pass
@abstractmethod
def stop_engine(self):
pass
class Motorcycle(Vehicle):
def start_engine(self):
print(f"{self.brand} motorcycle engine started")
def stop_engine(self):
print(f"{self.brand} motorcycle engine stopped")
motorcycle = Motorcycle("Yamaha")
motorcycle.start_engine()
motorcycle.stop_engine()
# Yamaha motorcycle engine started
# Yamaha motorcycle engine stopped
Dit laat zien hoe abstracte klassen implementatieflexibiliteit mogelijk maken terwijl ze een consistente interface afdwingen.
Voorbeeld van een abstracte basisklasse in Python
Nu we hebben gezien hoe abstracte basisklassen een contract voor subklassen definiëren, bekijken we hoe concrete klassen aan deze eisen voldoen door alle abstracte methoden te implementeren.
Concrete klasse die erft van een abstracte klasse
Een subklasse die elke abstracte methode van een abstracte klasse implementeert, wordt een concrete klasse genoemd. Dit betekent dat de concrete klasse specifieke implementaties biedt voor alle vereiste methoden en zo het contract van de abstracte klasse naleeft.
Bijvoorbeeld:
from abc import ABC, abstractmethod
class Appliance(ABC):
@abstractmethod
def turn_on(self):
pass
@abstractmethod
def turn_off(self):
pass
class WashingMachine(Appliance):
def turn_on(self):
print("Washing machine is now ON")
def turn_off(self):
print("Washing machine is now OFF")
machine = WashingMachine()
machine.turn_on()
machine.turn_off()
# Washing machine is now ON
# Washing machine is now OFF
Instanties maken en regels afdwingen
Python voorkomt dat je een abstracte klasse direct instantieert. Dit is een essentieel aspect van abstracte klassen, omdat het garandeert dat elke subklasse die uit de abstracte klasse wordt afgeleid zich houdt aan het vereiste contract dat door de abstracte methoden wordt opgelegd.
Als je bijvoorbeeld probeert appliance = Appliance() te instantieren, wordt er een TypeError opgeworpen.
Deze beperking garandeert dat abstracte klassen uitsluitend als blauwdrukken fungeren en niet verkeerd worden gebruikt. Door alle abstracte methoden in WashingMachine te implementeren, staat Python het maken van instanties van WashingMachine toe, terwijl het contract dat in Appliance is vastgelegd behouden blijft. Deze afdwinging verbetert de integriteit van de codebase door te garanderen dat elke functionaliteit die in de abstracte klasse is gespecificeerd, volledig wordt geïmplementeerd in de concrete subklassen.
Abstracte properties en initialisatie
Met deze basis duiken we dieper in hoe Python abstracte properties ondersteunt met de decorators @property en @abstractmethod, zodat ontwikkelaars naast methoden ook consistentie van attributen kunnen afdwingen.
Abstracte properties gebruiken in Python
Abstracte klassen kunnen naast methoden ook properties specificeren die subklassen moeten implementeren. Met deze functie kunnen ontwikkelaars een uniforme interface afdwingen voor properties die subklassen, naast methoden, moeten declareren.
Om te garanderen dat elke subklasse zijn eigen implementatie levert, kunnen abstracte properties worden gespecificeerd met de decorator @property in combinatie met @abstractmethod. Deze aanpak is vooral handig bij het maken van klassen die read-only of berekende attributen nodig hebben die essentieel zijn voor de werking van de klasse.
Voorbeeld: abstracte klasse met properties
Hier is een voorbeeld:
from abc import ABC, abstractmethod
class Animal(ABC):
@property
@abstractmethod
def sound(self):
pass
class Bird(Animal):
@property
def sound(self):
return "Chirp"
bird = Bird()
print(bird.sound)
# Chirp
De Bird-klasse voldoet aan de eis van de abstracte klasse Animal voor de property sound.
Wanneer gebruik je abstracte klassen in Python
Abstracte klassen zijn ideaal in scenario's zoals:
- Bij het ontwerpen van frameworks of libraries waar bepaald gedrag moet worden afgedwongen: In complexe systemen kunnen abstracte klassen een uniforme set richtlijnen of interfaces vastleggen waar alle subklassen aan moeten voldoen, wat consistentie garandeert en fouten vermindert.
- Het implementeren van consistente API's tussen klassen: Door abstracte methoden te definiëren, kunnen ontwikkelaars garanderen dat alle afgeleide klassen een gestandaardiseerde en voorspelbare manier bieden om met de applicatie of library te communiceren.
- Het bieden van een basisraamwerk voor een klassenhiërarchie: Abstracte klassen kunnen als leidraad dienen voor het creëren van een hiërarchie van verwante klassen. Door in de abstracte klasse gedeelde gedragingen en kenmerken te definiëren en aanpassing in subklassen toe te staan, bevordert deze structuur hergebruik en vermindert duplicatie.
Best practices
Gebruik abstracte klassen wanneer je een precies contract voor subklassen moet vastleggen. Abstracte klassen zijn nuttig als je een specifieke structuur of gedrag wilt afdwingen op meerdere afgeleide klassen. Ze helpen ervoor te zorgen dat elke subklasse een standaardontwerp volgt, wat de voorspelbaarheid van de code verbetert en onderhoud vereenvoudigt.
Gebruik geen abstracte klassen als elke methode een standaardimplementatie kan hebben. In sommige gevallen is een concrete basisklasse een betere optie om complexiteit te verminderen, terwijl je de mogelijkheid behoudt om gedeelde functionaliteit te hergebruiken.
Zorg dat abstracte klassen duidelijk en eenvoudig zijn, en definieer alleen de belangrijkste attributen en methoden. Een abstracte klasse met te veel vereisten kan lastig te bouwen en te onderhouden zijn. Richt je in plaats daarvan op de essentiële aspecten die de afgeleide klassen moeten hebben.
Conclusie
Abstracte klassen maken deel uit van Python's OOP-gereedschapskist en zijn een krachtig hulpmiddel waarmee programmeurs betrouwbare en onderhoudbare programma's kunnen maken. Door abstracte klassen te definiëren en met behulp van de ABC-module een uniforme interface in subklassen af te dwingen, bevorder je duidelijkheid, hergebruik en uitbreidbaarheid in je applicaties. Het implementeren van abstracte klassen helpt je om betere, betrouwbaardere code te schrijven, ongeacht de omvang van het systeem waar je aan werkt.
Of je nu robuuste objectgeoriënteerde programma's ontwerpt, consistente interfaces afdwingt of schaalbare applicaties bouwt, het beheersen van abstracte klassen in Python vergroot je vermogen om efficiënte en onderhoudbare code te schrijven. Versterk je Python-kennis vandaag nog met onze uitgebreide Python Fundamentals skill track.
Veelgestelde vragen over abstracte klassen in Python
Hoe definieer je een abstracte methode in Python?
Een abstracte methode wordt gedefinieerd met de decorator @abstractmethod uit de abc-module. Het dient als placeholder en moet door elke subklasse worden overschreven.
Kun je een abstracte klasse in Python instantiëren?
Nee, je kunt een abstracte klasse niet direct instantiëren. Python zal een TypeError geven als je een object van een abstracte klasse probeert te maken.
Wat is het doel van de `abc`-module in Python?
De abc-module biedt de klasse ABC en de decorator abstractmethod om abstracte klassen en methoden in Python te definiëren en af te dwingen.
Kan een abstracte klasse reguliere (concrete) methoden hebben?
Ja, een abstracte klasse kan reguliere (concrete) methoden met een implementatie hebben. Deze methoden kunnen worden geërfd en gebruikt door subklassen.

