Reuse the parent, then extend it.
Repeating title, author, and year initialization in every child class makes code harder to maintain.
class Book:
def __init__(self, title, author, year):
self.title = title
self.author = author
self.year = year
self.is_available = True
def display_info(self):
print(f"{self.title} - {self.author}")
class EBook(Book):
def __init__(self, title, author, year, file_size):
super().__init__(title, author, year)
self.file_size = file_size
def display_info(self):
super().display_info()
print(f"File size: {self.file_size} MB")
ebook = EBook("Dune", "Frank Herbert", 1965, 5.2)
ebook.display_info()super().__init__() calls the parent constructor for shared attributes. EBook then saves file_size. This simplified Book example still represents the full project’s shared behavior.
Dune - Frank Herbert
File size: 5.2 MBOverriding display_info() replaces the inherited method. When we call display_info() on an EBook object, Python uses the method defined in EBook first, if one exists. Calling super().display_info() keeps the parent output before adding new output.
Keep in mind: super() is useful when you want parent behavior too. It is not required for every overridden method.
class PrintedBook(Book):
def display_info(self):
print("Printed edition")This override prints only its own message because it does not call super().display_info().
