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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
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:
1 2 3 4 5 6 7 8 9 10 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
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 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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}.") |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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()!") |