Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære Concrete Methods in Abstract Classes | ABCs in Depth
Python Abstract Base Classes

Concrete Methods in Abstract Classes

Sveip for å vise menyen

An abstract class is not purely abstract. It can contain fully implemented concrete methods that all subclasses inherit without needing to override. This is what makes ABCs more powerful than simple interfaces – they can provide shared behavior alongside enforced contracts.

Shared Logic in the Base Class

Concrete methods in an ABC capture behavior that is common to all implementations, reducing code duplication:

12345678910111213141516171819202122232425262728293031323334353637383940414243
from abc import ABC, abstractmethod # ABC with both abstract and concrete methods class ReportExporter(ABC): @abstractmethod def serialize(self, data): pass @abstractmethod def get_extension(self): pass # Concrete method – same for all subclasses def export(self, data, filename): content = self.serialize(data) full_path = f"{filename}.{self.get_extension()}" print(f"Exporting {len(content)} bytes to {full_path}") return full_path class CsvExporter(ReportExporter): def serialize(self, data): headers = ",".join(data[0].keys()) rows = [",".join(str(value) for value in row.values()) for row in data] return "\n".join([headers] + rows) def get_extension(self): return "csv" class JsonExporter(ReportExporter): def serialize(self, data): import json return json.dumps(data) def get_extension(self): return "json" records = [{"id": "TX-001", "amount": 4500.0}, {"id": "TX-002", "amount": 1200.0}] csv_exporter = CsvExporter() csv_exporter.export(records, "transactions") # Uses shared export() logic json_exporter = JsonExporter() json_exporter.export(records, "transactions")

Both exporters reuse export() without reimplementing it. The abstract methods define the variable parts; the concrete method defines the fixed orchestration.

The Template Method Pattern

This is a formal design pattern – an abstract class defines the skeleton of an algorithm in a concrete method, and delegates the variable steps to abstract methods in subclasses:

123456789101112131415161718192021222324252627282930313233343536373839
from abc import ABC, abstractmethod # Template method pattern – algorithm skeleton in the base class class DataPipeline(ABC): # Template method – defines the fixed pipeline steps def run(self): raw_data = self.extract() clean_data = self.transform(raw_data) self.load(clean_data) print(f"Pipeline complete: {len(clean_data)} records processed") @abstractmethod def extract(self): pass @abstractmethod def transform(self, data): pass @abstractmethod def load(self, data): pass class SalesPipeline(DataPipeline): def extract(self): return [ {"region": "North", "revenue": 142500.0}, {"region": "South", "revenue": -500.0}, # Invalid – negative {"region": "East", "revenue": 98000.0}, ] def transform(self, data): return [record for record in data if record["revenue"] > 0] def load(self, data): print(f"Loading {len(data)} records to data warehouse") pipeline = SalesPipeline() pipeline.run() # Calls extract → transform → load in the correct order

Overriding Concrete Methods

Subclasses can override concrete methods if they need different behavior – the ABC does not prevent it:

1234567891011121314151617181920212223242526272829
from abc import ABC, abstractmethod class Notifier(ABC): @abstractmethod def send(self, message): pass # Concrete method with default behavior def notify_all(self, recipients, message): for recipient in recipients: self.send(f"To {recipient}: {message}") class EmailNotifier(Notifier): def send(self, message): print(f"EMAIL: {message}") class SmsNotifier(Notifier): def send(self, message): print(f"SMS: {message}") # Overriding the concrete method for SMS-specific behavior def notify_all(self, recipients, message): truncated = message[:160] # SMS character limit super().notify_all(recipients, truncated) recipients = ["alice@example.com", "bob@example.com"] EmailNotifier().notify_all(recipients, "Q3 report is ready.") SmsNotifier().notify_all(recipients, "Q3 report is ready.")
question mark

What design pattern is implemented when an ABC defines the steps of an algorithm in a concrete method and delegates variable parts to abstract methods?

Velg det helt riktige svaret

Alt var klart?

Hvordan kan vi forbedre det?

Takk for tilbakemeldingene dine!

Seksjon 2. Kapittel 2

Spør AI

expand

Spør AI

ChatGPT

Spør om hva du vil, eller prøv ett av de foreslåtte spørsmålene for å starte chatten vår

Seksjon 2. Kapittel 2
some-alt