|
| 1 | +# **Inheritance** |
| 2 | +It is the mechanism that allows you to create a hierarchy of classes that share a set of properties and methods by deriving a class from another class. Inheritance is the capability of one class to derive or inherit the properties from another class. |
| 3 | + |
| 4 | +## **Benefits of Inheritance** |
| 5 | +* It represent real world relationship well |
| 6 | +* It provides the reusability of a code. We don't have have to write the same code again and again. Also, it aloows us to add more features to a class without modifying it. |
| 7 | +* Inheritance offers simple, understandable model structure. |
| 8 | +* It is transitive in nature, which means that is class B inherits from another class A, then all the subclasses B would automatically inherit from class A. |
| 9 | + |
| 10 | +## **Syntax** |
| 11 | + |
| 12 | +```py |
| 13 | +class BaseClass: |
| 14 | + {Body} |
| 15 | +class DerivedClass(BaseClass): |
| 16 | + {Body} |
| 17 | +``` |
| 18 | + |
| 19 | +**Example:** |
| 20 | +```py |
| 21 | +class Person(object): |
| 22 | + # Constructor |
| 23 | + def __init__(self, name, age): |
| 24 | + self.age = age |
| 25 | + self.name = name |
| 26 | + # To get name |
| 27 | + def getName(self): |
| 28 | + return self.name |
| 29 | + def getAge(self): |
| 30 | + return self.age |
| 31 | + def isEmployeed(self): |
| 32 | + return False |
| 33 | + |
| 34 | +class Employee(Person): |
| 35 | + def isEmployee(self): |
| 36 | + return True |
| 37 | +# An object of a Person |
| 38 | +emp = Person("Gorilla", 100) |
| 39 | +print("Object of Person: ") |
| 40 | +print(emp.getName()) |
| 41 | +print(emp.getAge()) |
| 42 | +print(emp.isEmployeed()) |
| 43 | +# An object of a Employee |
| 44 | +emp = Employee("Dinosaur", 66502) |
| 45 | +print("Object of Employee: ") |
| 46 | +print(emp.getName()) |
| 47 | +print(emp.getAge()) |
| 48 | +print(emp.isEmployee()) |
| 49 | + |
| 50 | +""" |
| 51 | +Output: |
| 52 | +Object of Person: |
| 53 | +Gorilla |
| 54 | +100 |
| 55 | +False |
| 56 | +Object of Employee: |
| 57 | +Dinosaur |
| 58 | +66502 |
| 59 | +True |
| 60 | +""" |
| 61 | +``` |
| 62 | + |
| 63 | +* `super()` function is a built-in function that returns the objects that represented the parent class. It allows to access the parent class methods and attributes in the child class. |
| 64 | + |
| 65 | +## **Different types of Inheritance** |
| 66 | +* **Single Inheritance :** When a child class inherits from ***only one parent class***, it is called Single Inheritance. [Example is above] |
| 67 | +* **Multiple Inheritance :** When a child class inherits from ***multiple parent classes***, it is called Multiple Inheritance. |
| 68 | +* **Multilevel Inheritance :** When we have a child and grandchild relationship. This means that a child class will inherit from its parent class, which in turn is inheriting from its parent class. |
| 69 | +* **Hierarchial Inheritance :** More than one derived class can be created from a single base. |
| 70 | +* **Hybrid Inheritance :** This forms combines more than one form if inheritance. Basically, it is a blend of more than one type of inheritance. |
| 71 | + |
| 72 | +## **Multiple Inheritance** |
| 73 | +```py |
| 74 | +# When a child class inherits from multiple parent classes, it is called Multiple Inheritance. |
| 75 | + |
| 76 | +class Base1(object): |
| 77 | + # constructors |
| 78 | + def __init__(self): |
| 79 | + self.str1 = "USA" |
| 80 | + print("Base1 Class") |
| 81 | +class Base2(object): |
| 82 | + # constructors |
| 83 | + def __init__(self): |
| 84 | + self.str2 = "Germany" |
| 85 | + print("Base2 Class") |
| 86 | +class Derived(Base1, Base2): |
| 87 | + def __init__(self): |
| 88 | + # Calling constructors of base classes |
| 89 | + Base1.__init__(self) |
| 90 | + Base2.__init__(self) |
| 91 | + print("Derived Class") |
| 92 | + def printStr(self): |
| 93 | + print("Countries:", self.str1, "", self.str2) |
| 94 | +obj = Derived() |
| 95 | +obj.printStr() |
| 96 | + |
| 97 | +""" |
| 98 | +Output: |
| 99 | +Base1 Class |
| 100 | +Base2 Class |
| 101 | +Derived Class |
| 102 | +Countries: USA Germany |
| 103 | +""" |
| 104 | +``` |
| 105 | +## **Multilevel Inheritance** |
| 106 | +```py |
| 107 | +# When we have a child and grandchild relationship. This means that a child class will inherit from its parent class, which in turn is inheriting from its parent class. |
| 108 | +class Base(object): |
| 109 | + # constructor |
| 110 | + def __init__(self, name): |
| 111 | + self.name = name |
| 112 | + def getName(self): |
| 113 | + return self.name |
| 114 | + |
| 115 | +class Child(Base): |
| 116 | + def __init__(self,name,age): |
| 117 | + Base.__init__(self,name) |
| 118 | + self.age = age |
| 119 | + def getAge(self): |
| 120 | + self.age = age |
| 121 | + |
| 122 | +class grandChild(Child): |
| 123 | + def __init__(self, name, age, address): |
| 124 | + Child.__init__(self,name,age) |
| 125 | + self.address = address |
| 126 | + def getAddress(self): |
| 127 | + return self.address |
| 128 | +objGrandChild = grandChild("Richard", 23, "Boston") |
| 129 | +print("Name:", objGrandChild.name) |
| 130 | +print("Age:", objGrandChild.age) |
| 131 | +print("Address:", objGrandChild.address) |
| 132 | + |
| 133 | +""" |
| 134 | +Output: |
| 135 | +Name: Richard |
| 136 | +Age: 23 |
| 137 | +Address: Boston |
| 138 | +""" |
| 139 | +``` |
| 140 | + |
| 141 | +## **Method Chaining** |
| 142 | +Calling multiple methods automatically each call performs an actions on the same object and returns self. |
| 143 | +```py |
| 144 | +class Car: |
| 145 | + def turn_on(self): |
| 146 | + print("You started the engine") |
| 147 | + return self |
| 148 | + def drive(self): |
| 149 | + print("You drove the car") |
| 150 | + return self |
| 151 | + def brake(self): |
| 152 | + print("You applied the brake on the Car") |
| 153 | + return self |
| 154 | + def turn_off(self): |
| 155 | + print("You turned off the engine") |
| 156 | + return self |
| 157 | +car = Car() |
| 158 | +print("Without Method Chaining: ") |
| 159 | +car.turn_on() |
| 160 | +car.drive() |
| 161 | +car.brake() |
| 162 | +car.turn_off() |
| 163 | + |
| 164 | +# Method Chaining |
| 165 | +print("\nWith Method Chaining: ") |
| 166 | +car.turn_on().drive() |
| 167 | +car.brake().turn_off() |
| 168 | +car.turn_on().drive().brake().turn_off() |
| 169 | + |
| 170 | +""" |
| 171 | +Output: |
| 172 | +Without Method Chaining: |
| 173 | +You started the engine |
| 174 | +You drove the car |
| 175 | +You applied the brake on the Car |
| 176 | +You turned off the engine |
| 177 | +
|
| 178 | +With Method Chaining: |
| 179 | +You started the engine |
| 180 | +You drove the car |
| 181 | +You applied the brake on the Car |
| 182 | +You turned off the engine |
| 183 | +You started the engine |
| 184 | +You drove the car |
| 185 | +You applied the brake on the Car |
| 186 | +You turned off the engine |
| 187 | +""" |
| 188 | +``` |
| 189 | + |
| 190 | +## `super()` Functions |
| 191 | +Function used to give access to the method of a parent class. Returns a temporary object of a parent class when used. |
| 192 | + |
| 193 | +### **Code without the super function:** |
| 194 | + |
| 195 | +```py |
| 196 | +class Rectangle: |
| 197 | + pass |
| 198 | +class Square(Rectangle): |
| 199 | + def __init__(self,length, width): |
| 200 | + self.length = length |
| 201 | + self.width = width |
| 202 | + def area(self): |
| 203 | + return self.length * self.width |
| 204 | +class Cube(Rectangle): |
| 205 | + def __init__(self,length, width, height): |
| 206 | + self.length = length |
| 207 | + self.width = width |
| 208 | + self.height = height |
| 209 | + def volume(self): |
| 210 | + return self.length * self.width * self.width |
| 211 | +square_obj = Square(3,3) |
| 212 | +cube_obj = Cube(3,3,3) |
| 213 | +a = square_obj.area() |
| 214 | +b = cube_obj.volume() |
| 215 | +print(a) |
| 216 | +print(b) |
| 217 | + |
| 218 | +""" |
| 219 | +Output: |
| 220 | +9 |
| 221 | +27 |
| 222 | +""" |
| 223 | +``` |
| 224 | +### **Code with the super function:** |
| 225 | + |
| 226 | +```py |
| 227 | +class Rectangle: |
| 228 | + def __init__(self,length,width): |
| 229 | + self.length = length |
| 230 | + self.width = width |
| 231 | + |
| 232 | +class Square(Rectangle): |
| 233 | + def __init__(self,length,width): |
| 234 | + super().__init__(length,width) |
| 235 | + def area(self): |
| 236 | + return self.length * self.width |
| 237 | + |
| 238 | +class Cube(Rectangle): |
| 239 | + def __init__(self,length, width, height): |
| 240 | + super().__init__(length, width) |
| 241 | + self.height = height |
| 242 | + def volume(self): |
| 243 | + return self.length * self.width * self.width |
| 244 | + |
| 245 | +square_obj = Square(3,3) |
| 246 | +cube_obj = Cube(3,3,3) |
| 247 | +a = square_obj.area() |
| 248 | +b = cube_obj.volume() |
| 249 | +print(a) |
| 250 | +print(b) |
| 251 | + |
| 252 | +""" |
| 253 | +Output: |
| 254 | +9 |
| 255 | +27 |
| 256 | +""" |
| 257 | +``` |
0 commit comments