Skip to content

Commit 069d084

Browse files
authored
Create abstract-classes.md
1 parent c0a6d41 commit 069d084

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed

python/abstract-classes.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Abstract classes
2+
3+
Abstract class is an extension of a basic class. Like a basic class, an abstract class has methods and state. Unlike a basic class, it inherits the `ABC` class and has at least one `abstractmethod`. That means we cannot create an instance directly from its constructor. We will create an abstract class and two concrete classes.
4+
5+
## Creating the classes
6+
7+
First let's create an abstract definition of an employee. Any employee can work and relax. The way that one type of employee can work and relax is different from another type of employee.
8+
9+
```python
10+
from abc import ABC, abstractmethod
11+
12+
class Employee(ABC):
13+
def __init__(self, name, title):
14+
self.name = name
15+
self.title = title
16+
17+
def __str__(self):
18+
return self.name
19+
20+
@abstractmethod
21+
def do_work(self):
22+
"""Do something for work."""
23+
raise NotImplementedError
24+
25+
@abstractmethod
26+
def do_relax(self):
27+
"""Do something to relax."""
28+
raise NotImplementedError
29+
```
30+
31+
Then we can create a concrete definition of an engineer. The Engineer class is concrete because it implements every `abstractmethod` that was not implemented above. Notice that we leverage the parent's constructor when creating this object. We also define `do_refactor` for an engineer, which is something that a manager prefers not to do.
32+
33+
```python
34+
class Engineer(Employee):
35+
def __init__(self, name, title, skill):
36+
super().__init__(name, title)
37+
self.skill = skill
38+
39+
def do_work(self):
40+
return f"{self} is coding in {self.skill}"
41+
42+
def do_relax(self):
43+
return f"{self} is watching YouTube"
44+
45+
def do_refactor(self):
46+
"""Do the hard work of refactoring code, unlike managers."""
47+
return f"{self} is refactoring code"
48+
```
49+
50+
Now we create a oncrete definition of a manager. The Manager class is concrete for the same reasons as the Engineer class is concrete. Notice that a manager has direct reports and has the responsibility of hiring people on the team, unlike an engineer.
51+
52+
```python
53+
class Manager(Employee):
54+
def __init__(self, name, title, direct_reports):
55+
super().__init__(name, title)
56+
self.direct_reports = direct_reports
57+
58+
def do_work(self):
59+
return f"{self} is meeting up with {len(self.direct_reports)} reports"
60+
61+
def do_relax(self):
62+
return f"{self} is taking a trip to the Bahamas"
63+
64+
def do_hire(self):
65+
"""Do the hard work of hiring employees, unlike engineers."""
66+
return f"{self} is hiring employees"
67+
```
68+
69+
## Using the classes
70+
71+
Declare two engineers:
72+
73+
```python
74+
engineer_john = Engineer("John Doe", "Software Engineer", "Android")
75+
engineer_jane = Engineer("Jane Doe", "Software Engineer", "iOS")
76+
```
77+
78+
These engineers are employees but not managers:
79+
```python
80+
assert all(isinstance(engineer, Employee) for engineer in engineers)
81+
assert all(not isinstance(engineer, Manager) for engineer in engineers)
82+
```
83+
84+
Engineers can work, relax and refactor:
85+
```python
86+
assert engineer_john.do_work() == "John Doe is coding in Android"
87+
assert engineer_john.do_relax() == "John Doe is watching YouTube"
88+
assert engineer_john.do_refactor() == "John Doe is refactoring code"
89+
```
90+
91+
Declare manager with engineers as direct reports:
92+
```python
93+
manager_max = Manager("Max Doe", "Engineering Manager", engineers)
94+
```
95+
96+
Managers are employees but not engineers:
97+
```python
98+
assert isinstance(manager_max, Employee)
99+
assert not isinstance(manager_max, Engineer)
100+
```
101+
102+
Managers can work, relax and hire:
103+
```python
104+
assert manager_max.do_work() == "Max Doe is meeting up with 2 reports"
105+
assert manager_max.do_relax() == "Max Doe is taking a trip to the Bahamas"
106+
assert manager_max.do_hire() == "Max Doe is hiring employees"
107+
```

0 commit comments

Comments
 (0)