Inheritance
Shelfwise starts selling e-books. They have a title, a price and an author like paper books, but no weight and no shipping. Copying the whole Product class and editing it would create two copies of the same knowledge. Inheritance lets EBook reuse what Product already has and change only what differs. Used carelessly, it also creates some of the worst tangles in object-oriented code.
The rule
Inherit only when "is a" holds everywhere the parent is used.
A subclass inherits the fields and methods of its parent (or base) class, can add new ones, and can override methods to behave differently.
class Product:
def __init__(self, title, price):
self.title = title
self.price = price
def delivery_days(self):
return 3
class EBook(Product):
def __init__(self, title, price, file_url):
super().__init__(title, price) # reuse the parent's setup
self.file_url = file_url
def delivery_days(self): # override
return 0EBook gets title and price for free, adds file_url, and replaces delivery_days. Any code that works with a Product also works with an EBook, because an e-book is a product.
Inheritance is a tight bond. The subclass depends on the parent's inner workings, so a change to the parent can break every child. That is why the "is a" test has to hold everywhere, not just in one sentence:
EBook(Product): an e-book is a product wherever products are listed, priced and ordered. Good.Cart(list): a cart uses a list, but inheriting hands callerssort,clearandinsert, which skip every cart rule. Bad.Customer(Address): a customer has an address. Bad.
When the honest phrase is "has a" or "uses a", hold the other object in a field instead.
The shortcut
Say "every X is a Y, and anything I can do with a Y makes sense for an X". If both halves are true, inherit. If either is false, use a field.
Part one
"Every gift card is a product." True: it has a title and a price, and it can be ordered.
The trap is inheriting just to reuse a few methods. Reuse is a side effect of a true "is a", never a reason on its own. Deep hierarchies, five levels down, are usually this trap repeated.
Drills
Answer fast — trust the rule.
Which relationship is a sound use of inheritance?
What does super().__init__(title, price) do inside EBook.__init__?
EBook defines its own delivery_days that returns 0. What is this called?
Why is Cart(list) a poor design even though a cart holds items?
Remember
- Inherit only when "is a" holds everywhere the parent is used.
- Test both halves: every X is a Y, and everything done with a Y makes sense for an X.
- Trap: inheriting only to reuse code; "has a" means a field, not a parent.
