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.
Python - OOP - Inheriting from Abstract Class

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()!")