Trying to understand abstract classes, I created a simple model:
from abc import ABC, abstractmethod
class Publication(ABC):
def __init__(self, title):
self.title = title
@abstractmethod
def Description(self):
pass
class Periodical(Publication):
def __init__(self, title, publisher):
super().__init__(title)
self.publisher = publisher
class Book(Publication):
def __init__(self, title, author):
super().__init__(title)
self.author = author
def Description(self):
print(f'Book: {self.title} ({self.author})')
class Magazine(Periodical):
def __init__(self, title, publisher):
super().__init__(title, publisher)
def Description(self):
print(f'Magazine: {self.title} ({self.publisher})')
class Newspaper(Periodical):
def __init__(self, title, publisher):
super().__init__(title, publisher)
def Description(self):
print(f'Newspaper: {self.title} ({self.publisher})')
book = Book('Thoughts', 'A. Einstein')
magazine = Magazine('Sailing', 'M. Polo')
newspaper = Newspaper('Daily Joke', 'Ms. Maisel')
book.Description()
magazine.Description()
newspaper.Description()
In Publication
I define Description()
as abstract method. If I don't implement it, e.g. in class Newspaper
, an error is thrown: TypeError: Can't instantiate abstract class Newspaper with abstract method Description
. That's what I intended.
But why is it possible to create Periodical
from Publication
without implementing Description()
?
CodePudding user response:
You are not required to provide concrete implementations of abstract methods in a subclass. A subclass that does not do so simply remains an abstract base class itself.
Only when you try to instantiate a class is there a check for abstract methods that haven't been override. If there are, instantiation fails. You couldn't instantiate Periodical
directly, but the class itself is just another abstract base class, with its subclasses Book
, Magazine
, and Newspaper
being made concrete by implementing Description
.
# Class is defined...
>>> Periodical
<class '__main__.Periodical'>
# ... but you can't instantiate it
>>> Periodical()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Periodical with abstract method Description