Python – Abstraction and Inheritance – Video
Abstract classes in Python are classes that inherit from the ABC (Abstract base class). In the video below, I have solved a problem, showing how 2 classes inherit from an abstract class and implement its methods.
The abstract class is PaperProduct, with 2 abstract methods:
- change_title()
- change_price()
The classes, inheriting from PaperProduct are the following 2 – Newspaper and Book. Newspaper simply implements its methods, while Book has 2 additional methods:
- add_review()
- __str__()
At the end, this is some input and some expected output:
Input:
book1 = Book(20, 20.5, "Fairy Tales", "J.K.J.")
book1.change_price(30)
book1.change_price(305)
book1.change_title("Funny Tales")
book1.add_review("A great and interesting book.", "Jo")
book1.add_review("Not that great.", "Joanna")
print(book1)
newspaper = Newspaper(30, 20, "Daily Sofia News", "daily")
print(newspaper.price)
newspaper.change_price(10)
print(newspaper.price)
book2 = Book(20, 20.5, "Tales", "J.K.J.")
book2.change_title("Fairy")
Expected output:
Price of the book is changed. It was 20.5. New price is 31.2. Price of the book is changed. It was 31.2. New price is 306.2. Book Funny Tales has edited its title. The book 'Funny Tales' is written by J.K.J. on 2020-04-05 23:38:36.117617 The following 2 reviews are available: 'A great and interesting book.' by Jo'Not that great.' by Joanna 20 Newspaper now costs 9.0. 9.0 Book Special Edition:Fairy has edited its title.
The code from the video is available here – https://github.com/Vitosh/Python_personal/tree/master/YouTube/001_Abstraction
from papers.paper_product import PaperProduct
class Book(PaperProduct):
def __init__(self, count_pages: int, price: float, title: str, author: str):
super().__init__(count_pages, price, title)
self.reviews = []
self.author = author
def change_title(self, new_title):
if len(new_title) < 10:
new_title = "Special Edition:" + new_title
self.title = new_title
print(f"Book {new_title} has edited its title.")
def change_price(self, price):
old_price = self.price
new_price = price + 1.2
self.price = new_price
print(f"Price of the book is changed. It was {old_price}. New price is {new_price}.")
def add_review(self, review, user):
self.reviews.append((review, user))
def reviews_count(self):
return len(self.reviews)
def __str__(self):
result = f"The book '{self.title}' is written by {self.author} on {self.issue_date}\n"
result += f"The following {self.reviews_count()} reviews are available:\n"
for review in self.reviews:
result += f"'{review[0]}' by {review[1]}"
return result
from papers.paper_product import PaperProduct
class Newspaper(PaperProduct):
def __init__(self, count_pages: int, price: float, title: str, period: str):
super().__init__(count_pages, price, title)
self.period = period
self.correctors = []
def change_title(self, new_title):
self.title = new_title
print(f"Newspaper changed its title. New title is {self.title}.")
def change_price(self, price):
self.price = price * 0.9
print(f"Newspaper now costs {self.price}.")
from _datetime import datetime
from abc import ABC, abstractmethod
class PaperProduct(ABC):
@abstractmethod
def __init__(self, count_pages, price, title):
self.count_pages = count_pages
self.price = price
self.title = title
self.issue_date = datetime.now()
@abstractmethod
def change_title(self, new_title):
raise NotImplementedError("Subclasses must override change_title()!")
@abstractmethod
def change_price(self, price):
raise NotImplementedError("Subclasses must override change_price()!")