Published Sept. 4, 2023, 6:36 p.m.
Introduction:
Today's lesson will focus on exploring the concept of inheritance in object-oriented programming. We'll delve into two essential relationships in OOP: the "Has-A" relationship, which involves objects working together, and the "IS-A" relationship, which defines class connections. Additionally, we'll compare "IS-A" and "HAS-A" relationships and discuss the choices for using composition vs. aggregation when building complex software systems.
🔹 Exploring Inheritance:
Using Members of One Class Inside Another Class
In object-oriented programming, we can use the features of one class inside another class in different ways:
By Composition (Has-A Relationship): This means that we create an object of one class inside another class. This way, we can use the data and functions of the first class in the second class. Composition (Has-A Relationship) helps us reuse code and avoid repetition.
# Define the Engine class with two attributes 'a' and 'b' and a function 'm1'
class Engine:
a = 10 # Class attribute 'a' with value 10
def __init__(self):
self.b = 20 # Instance attribute 'b' with value 20
def m1(self):
print('Engine Specific Functionality')
# Define the Car class
class Car:
def __init__(self):
# Make an object of the Engine class inside the Car class
self.engine = Engine()
def m2(self):
print('Car using Engine Class Functionality')
# Use and print the attributes and call the function of the Engine class
print(self.engine.a)
print(self.engine.b)
self.engine.m1()
# Make an object of the Car class and show how it works
c = Car()
c.m2()
Output:
Car using Engine Class Functionality
10
20
Engine Specific Functionality
Explanation: In this example, we have an Engine
class with two attributes a
and b
, and a function m1
. The Car
class makes an object of the Engine
class, so it can use the data and functions of Engine
.
By Inheritance (IS-A Relationship): This means that one class inherits from another, creating a parent-child relationship. The child class can use the members of the parent class.
# Define the parent class X with two attributes 'a' and 'b' and a function 'm1'
class X:
a = 10 # Class attribute 'a' with value 10
def __init__(self):
self.b = 20 # Instance attribute 'b' with value 20
def m1(self):
print("m1 function of X class")
# Define the child class Y
class Y:
c = 30 # Class attribute 'c' with value 30
def __init__(self):
self.d = 40 # Instance attribute 'd' with value 40
def m2(self):
print("m2 function of Y class")
def m3(self):
# Make an object of class X inside class Y
x1 = X()
# Use and print the attributes and call the function of class X
print(x1.a)
print(x1.b)
x1.m1()
# Use the attributes of class Y and call the function 'm2' of class Y
print(Y.c)
print(self.d)
self.m2()
print("m3 function of Y class")
# Make an object of class Y and show how it works
y1 = Y()
y1.m3()
Output:
10
20
m1 function of X class
30
40
m2 function of Y class
m3 function of Y class
Explanation: In this example, we have a parent class X
and a child class Y
that inherits from X
. This creates an IS-A relationship. The child class, Y
, can use the data and functions of both X
and Y
.
In object-oriented programming, we often need to choose between IS-A (Inheritance) and HAS-A (Composition) relationships. These are two ways of using and extending classes. Let's see what they mean with a diagram and some code examples.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def eat_and_drink(self):
print('Eat Biryani and Drink Beer 🍽️🍻')
class Employee(Person):
def __init__(self, name, age, emp_no, emp_salary, car):
super().__init__(name, age)
self.emp_no = emp_no
self.emp_salary = emp_salary
self.car = car
def work(self):
print("Coding Python is very easy, just like drinking Chilled Beer 🐍🍺")
def emp_info(self):
print("Employee Name:", self.name)
print("Employee Age:", self.age)
print("Employee Number:", self.emp_no)
print("Employee Salary:", self.emp_salary)
print("Employee Car Info:")
self.car.get_info()
e = Employee('Durga', 48, 100, 10000, c) # Creating an Employee object
e.eat_and_drink()
e.work()
e.emp_info()
Output:
Eat Biryani and Drink Beer 🍽️🍻
Coding Python is very easy, just like drinking Chilled Beer 🐍🍺
Employee Name: Durga
Employee Age: 48
Employee Number: 100
Employee Salary: 10000
Employee Car Info:
Car Name: Innova
Model: 2.5V
Color: Grey
Car
class contains an instance of the Engine
class, but it doesn't inherit from it; it just uses its features.class Car:
def __init__(self, name, model, color):
self.name = name
self.model = model
self.color = color
def get_info(self):
print("\tCar Name: {}\n\tModel: {}\n\tColor: {}".format(self.name, self.model, self.color))
class Engine:
a = 10
def __init__(self):
self.b = 20
def m1(self):
print('Engine Specific Functionality 🚗💨')
c = Car("Innova", "2.5V", "Grey") # Creating a Car object
c.get_info()
Output:
Car Name: Innova
Model: 2.5V
Color: Grey
This example shows the difference between IS-A (Inheritance) and HAS-A (Composition) relationships, where Employee IS-A Person and Car HAS-A Engine. 👏👏👏
In object-oriented programming, we often need to decide how to combine and use classes. There are two ways of doing this: Composition and Aggregation. Let's see what they mean with some examples and a mix of both. 🚀
Composition 🌟
Composition means a strong connection between two classes, where one class has the other as a part. In Composition, the part class cannot live without the whole class. It's like a "whole-part" connection.
🔍 Example - Composition:
class Brain:
def __init__(self):
print("Creating a Brain 🧠")
class Robot:
def __init__(self):
print("Creating a Robot 🤖")
self.brain = Brain()
# Create a Robot object
r = Robot()
Output:
Creating a Robot 🤖
Creating a Brain 🧠
In this Composition example, a Robot
"has-a" Brain
. The Brain
is made as part of the Robot
, and the Robot
cannot work without it.
Aggregation 🧩
Aggregation means a weak connection between two classes, where one class can live without the other. It's like a "whole-part" connection, but the parts can live on their own.
🔍 Example - Aggregation:
class Book:
def __init__(self, title):
self.title = title
class Library:
def __init__(self, name):
self.name = name
self.books = []
def add_book(self, book):
self.books.append(book)
# Create a Library and Book objects
python = Book("Python for Beginners")
library = Library("City Library")
library.add_book(python)
Output:
No specific output in this case, as it's a structural example.
In this Aggregation example, a Library
"has" Book
s. However, the Book
objects can live independently of the Library
.
Mixing Composition and Aggregation 🤝
In real-life situations, you can mix both Composition and Aggregation. For example, a Library
may have Librarian
s (Aggregation) while each Librarian
has a Badge
(Composition).
Code Explanations:
🚀 Have fun coding with Composition and Aggregation! 😄