When a program starts to get big, classes might start to share functionality or we may lose sight of the purpose of a class’s inheritance structure. In order to alleviate issues like this, we can use the concept of abstraction.
Abstraction helps with the design of code by defining necessary behaviors to be implemented within a class structure. By doing so, abstraction also helps avoid leaving out or overlapping class functionality as class hierarchies get larger.
from abc import ABC, abstractmethod class Animal(ABC): def __init__(self, name): self.name = name @abstractmethod def make_noise(self): pass class Cat(Animal): def make_noise(self): print("{} says, Meow!".format(self.name)) class Dog(Animal): def make_noise(self): print("{} says, Woof!".format(self.name)) kitty = Cat("Maisy") doggy = Dog("Amber") kitty.make_noise() # "Maisy says, Meow!" doggy.make_noise() # "Amber says, Woof!"
Above we have Cat
and Dog
classes that inherit from Animal
. The Animal
class now inherits from an imported class ABC
, which stands for Abstract Base Class.
This is the first step to making Animal
an abstract class that cannot be instantiated. The second step is using the imported decorator @abstractmethod
on the empty method .make_noise()
.
The below line of code would throw an error.
an_animal = Animal("Scruffy") # TypeError: Can't instantiate abstract class Animal with abstract method make_noise
The abstraction process defines what an Animal
is but does not allow the creation of one. The .__init__()
method still requires a name, since we feel all animals deserve a name.
The .make_noise()
method exists since all animals make some form of noise, but the method is not implemented since each animal makes a different noise. Each subclass of Animal
is now required to define their own .make_noise()
method or an error will occur.
These are some of the ways abstraction supports the design of an organized class structure.
Instructions
Take a look at the code in script.py. The abstract class AbstractEmployee
is defined. It has all the logic that has previously existed in the Employee
class, except that the .say_id()
method is not implemented and has the @abstractmethod
decorator.
The Employee
class currently has no implementation.
Run the code and observe that e1.say_id()
is causing an AttributeError
since the Employee
class has no implementation.
Let’s fix this error:
- Make the
Employee
class inherit from theAbstractEmployee
class
Nice work! But wait, there’s still an error!
TypeError: Can't instantiate abstract class Employee with abstract methods say_id
The .say_id()
method in the AbstractEmployee
class uses the @abstractmethod
decorator. This means any class that inherits from AbstractEmployee
must implement a .say_id()
method.
Inside the Employee
class replace the pass
statement, then:
- Define a
say_id()
method that outputs a message withself.id
When complete you should see the output in the console.