forked from huangsam/ultimate-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathabstract_class.py
More file actions
114 lines (81 loc) · 3.58 KB
/
abstract_class.py
File metadata and controls
114 lines (81 loc) · 3.58 KB
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
from abc import ABC, abstractmethod
class Employee(ABC):
"""Abstract definition of an employee.
The `Employee` class is abstract because it inherits the `ABC` class
and has at least one `abstractmethod`. That means we cannot create
an instance directly from its constructor. Also, all subclasses
need to implement every `abstractmethod` in this class.
For more about abstract classes, click the link below:
https://www.python.org/dev/peps/pep-3119/
"""
def __init__(self, name, title):
self.name = name
self.title = title
def __str__(self):
return self.name
@abstractmethod
def do_work(self):
"""Do something for work."""
raise NotImplementedError
@abstractmethod
def do_relax(self):
"""Do something to relax."""
raise NotImplementedError
class Engineer(Employee):
"""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.
"""
def __init__(self, name, title, skill):
super().__init__(name, title)
self.skill = skill
def do_work(self):
return f"{self} is coding in {self.skill}"
def do_relax(self):
return f"{self} is watching YouTube"
def do_refactor(self):
"""Do the hard work of refactoring code, unlike managers."""
return f"{self} is refactoring code"
class Manager(Employee):
"""Concrete 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.
"""
def __init__(self, name, title, direct_reports):
super().__init__(name, title)
self.direct_reports = direct_reports
def do_work(self):
return f"{self} is meeting up with {len(self.direct_reports)} reports"
def do_relax(self):
return f"{self} is taking a trip to the Bahamas"
def do_hire(self):
"""Do the hard work of hiring employees, unlike engineers."""
return f"{self} is hiring employees"
def main():
# Declare two engineers
engineer_john = Engineer("John Doe", "Software Engineer", "Android")
engineer_jane = Engineer("Jane Doe", "Software Engineer", "iOS")
engineers = [engineer_john, engineer_jane]
# These engineers are employees but not managers
assert all(isinstance(engineer, Employee) for engineer in engineers)
assert all(not isinstance(engineer, Manager) for engineer in engineers)
# Engineers can work, relax and refactor
assert engineer_john.do_work() == "John Doe is coding in Android"
assert engineer_john.do_relax() == "John Doe is watching YouTube"
assert engineer_john.do_refactor() == "John Doe is refactoring code"
# Declare manager with engineers as direct reports
manager_max = Manager("Max Doe", "Engineering Manager", engineers)
# Managers are employees but not engineers
assert isinstance(manager_max, Employee)
assert not isinstance(manager_max, Engineer)
# Managers can work, relax and hire
assert manager_max.do_work() == "Max Doe is meeting up with 2 reports"
assert manager_max.do_relax() == "Max Doe is taking a trip to the Bahamas"
assert manager_max.do_hire() == "Max Doe is hiring employees"
if __name__ == "__main__":
main()