Abstract class and abstract methods are one of the pillars of Object Oriented Programming. In Python, an abstract class is a class, inheriting from Abstract Base Classes (ABC) library. And an abstract method is a method of this class, which cannot be initialized and has a decorator @abstractmethod.
About 1 year ago I wrote an article about refactoring a C# problem with abstract methods. Today, I have decided to solve a similar problem with live coding and with Python. So, the problem, as written by SoftUni, looks like this:
- Create an abstract class called Vehicle that should have abstract methods drive and refuel.
- Create 2 vehicles that inherit the Vehicle class (a Car and a Truck) and simulates driving and refueling them.
- Car and Truck both have fuel_quantity, fuel_consumption in liters per km and can be driven a given distance: drive(distance) and refueled with a given amount of fuel: refuel(fuel). It is summer, so both vehicles use air conditioners and their fuel consumption per km when driving is increased by 0.9 liters for the car and with 1.6 liters for the truck.
- Also, the Truck has a tiny hole in its tank and when it’s refueled it keeps only 95% of the given fuel. The car has no problems and adds all the given fuel to its tank. If a vehicle cannot travel the given distance, its fuel does not change.
And the tests that should work with it are these ones:
car = Car(20, 5) car.drive(3) print(car.fuel_quantity) car.refuel(10) print(car.fuel_quantity) |
2.299999999999997 12.299999999999997 |
truck = Truck(100, 15) truck.drive(5) print(truck.fuel_quantity) truck.refuel(50) print(truck.fuel_quantity) |
17.0 64.5 |
Yup. The video with the live coding is here:
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 34 35 36 37 38 39 40 41 42 |
from abc import ABC, abstractmethod class Vehicle(ABC): def __init__(self, fuel_quantity, fuel_consumption): self.fuel_quantity = fuel_quantity self.fuel_consumption = fuel_consumption @abstractmethod def drive(self, distance): raise NotImplementedError('Subclasses must override drive()!') @abstractmethod def refuel(self, fuel): raise NotImplementedError('Subclasses must override refuel()!') class Car(Vehicle): def __init__(self, fuel_quantity, fuel_consumption): super().__init__(fuel_quantity, fuel_consumption) def refuel(self, fuel): self.fuel_quantity += fuel def drive(self, distance): fuel_needed = distance * (self.fuel_consumption + 0.9) if fuel_needed <= self.fuel_quantity: self.fuel_quantity -= fuel_needed class Truck(Vehicle): def __init__(self, fuel_quantity, fuel_consumption): super().__init__(fuel_quantity, fuel_consumption) def refuel(self, fuel): fuel_to_enter = fuel * 0.95 self.fuel_quantity += fuel_to_enter def drive(self, distance): fuel_needed = distance * (self.fuel_consumption + 1.6) if fuel_needed <= self.fuel_quantity: self.fuel_quantity -= fuel_needed |
Enjoy it! 🙂