1+ class Parent :
2+ def __init__ (self , first_name : str , last_name : str ):
3+ self .first_name = first_name
4+ self .last_name = last_name
5+
6+ def get_name (self ) -> str :
7+ return f"{ self .first_name } { self .last_name } "
8+
9+
10+ class Child (Parent ):
11+ def __init__ (self , first_name : str , last_name : str ):
12+ super ().__init__ (first_name , last_name )
13+ self .previous_last_names = []
14+
15+ def change_last_name (self , last_name : str ) -> None :
16+ self .previous_last_names .append (self .last_name )
17+ self .last_name = last_name
18+
19+ def get_full_name (self ) -> str :
20+ suffix = ""
21+
22+ if len (self .previous_last_names ) > 0 :
23+ suffix = f" (previously { self .previous_last_names [0 ]} )"
24+
25+ return f"{ self .first_name } { self .last_name } { suffix } "
26+
27+
28+ person1 = Child ("Sara" , "Ali" )
29+
30+ print (person1 .get_name ())
31+ print (person1 .get_full_name ())
32+
33+ person1 .change_last_name ("Ahmed" )
34+
35+ print (person1 .get_name ())
36+ print (person1 .get_full_name ())
37+
38+
39+ person2 = Parent ("Sara" , "Ali" )
40+
41+ print (person2 .get_name ())
42+
43+ # These lines would cause errors because these methods
44+ # only exist in Child, not Parent:
45+
46+ # print(person2.get_full_name())
47+ # person2.change_last_name("Ahmed")
48+
49+ print (person2 .get_name ())
50+
51+ # This would also cause an error:
52+ # print(person2.get_full_name())
53+
54+
55+ # The important inheritance relationship is:
56+
57+ # Parent
58+ # │
59+ # ├── get_name()
60+ # │
61+ # ▼
62+ # Child
63+ # ├── inherits get_name()
64+ # ├── adds change_last_name()
65+ # └── adds get_full_name()
66+
67+ # So a Child can use the inherited Parent method, but a Parent cannot use methods that only exist in Child.
0 commit comments