Chapter 8: Object-Oriented Programming
8.3: Inheritance
Inheritance is one of the most powerful features in object-oriented programming, and it can greatly enhance the efficiency of your code. By allowing one class to inherit the attributes and methods of another class, you can create new classes that are built on top of existing ones, which can save a lot of time and effort.
For example, let's say you have a class that represents a car, with attributes like the make, model, and year, and methods like start_engine and accelerate. Now, let's say you want to create a new class for a specific type of car, like a sports car. Instead of starting from scratch and defining all of the attributes and methods for the sports car, you can simply create a new class that inherits from the car class, and then add or modify the attributes and methods as necessary. This way, you can reuse much of the code that you already wrote for the car class, and only focus on the changes that are specific to the sports car.
In Python, inheritance is implemented by defining a new class that takes the parent (base) class as an argument. The new class is called the child (derived) class, and the class it inherits from is called the parent (base) class. By using inheritance, you can create complex class hierarchies that can help you organize your code and make it more modular and reusable. Overall, inheritance is an essential concept in object-oriented programming, and mastering it can greatly improve your coding skills.
Let's understand inheritance through an example.
Suppose we have a base class called Animal
that represents a generic animal, with attributes like name
, age
, and a method called speak()
:
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def speak(self):
print(f"{self.name} makes a noise")
Now, we want to create a class Dog
that represents a dog, which is a specific type of animal. Instead of redefining all the attributes and methods of the Animal
class, we can inherit them using inheritance:
class Dog(Animal):
def __init__(self, name, age, breed):
super().__init__(name, age)
self.breed = breed
def speak(self):
print(f"{self.name} barks")
In this example, we define the Dog
class and inherit from the Animal
class. We use the super()
function to call the __init__
method of the parent class to initialize the name
and age
attributes. We also add a new attribute, breed
, specific to the Dog
class.
We also override the speak()
method of the Animal
class to better fit the behavior of a dog. This is called method overriding and is a common practice when using inheritance.
Now, when we create a Dog
object, it will have access to both the attributes and methods of the Animal
class, as well as any new attributes or methods we define in the Dog
class:
dog1 = Dog("Max", 3, "Labrador")
print(dog1.name) # Output: Max
print(dog1.age) # Output: 3
print(dog1.breed) # Output: Labrador
dog1.speak() # Output: Max barks
Inheritance is a fundamental concept in object-oriented programming that allows for the creation of more specialized classes. It enables code reuse from more general classes while providing the ability to customize or extend their behavior as needed. This makes inheritance a powerful tool for developers to create efficient and effective software solutions.
By using inheritance, developers can create a hierarchy of classes that share common characteristics, allowing for the implementation of complex systems. Additionally, inheritance helps reduce the complexity of code, making it easier to maintain and update over time. Therefore, it is essential to have a solid understanding of inheritance when developing software applications, as it can greatly improve the overall quality of the code and make it more scalable.
Exercise 8.3.1: Simple Inheritance
Implement a class hierarchy for different types of vehicles, using inheritance.
Instructions:
- Create a base class called
Vehicle
with attributesmake
,model
, andyear
. - Define a method
vehicle_info()
that prints the make, model, and year of the vehicle. - Create a class
Car
that inherits fromVehicle
and has an additional attributedoors
. - Create a class
Motorcycle
that inherits fromVehicle
and has an additional attributetype
. - Create instances of
Car
andMotorcycle
, and call thevehicle_info()
method for each.
Solution:
class Vehicle:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
def vehicle_info(self):
print(f"{self.year} {self.make} {self.model}")
class Car(Vehicle):
def __init__(self, make, model, year, doors):
super().__init__(make, model, year)
self.doors = doors
class Motorcycle(Vehicle):
def __init__(self, make, model, year, bike_type):
super().__init__(make, model, year)
self.type = bike_type
car1 = Car("Toyota", "Camry", 2020, 4)
car1.vehicle_info() # Output: 2020 Toyota Camry
motorcycle1 = Motorcycle("Yamaha", "R1", 2019, "Sport")
motorcycle1.vehicle_info() # Output: 2019 Yamaha R1
Exercise 8.3.2: Inheritance and Method Overriding
Create classes representing different types of bank accounts, using inheritance and method overriding.
Instructions:
- Create a base class
BankAccount
with attributesbalance
and a methoddeposit()
. - Define a method
withdraw()
that checks if the withdrawal amount is less than or equal to the balance, and updates the balance accordingly. - Create a class
SavingsAccount
that inherits fromBankAccount
and has an additional attributeinterest_rate
. - Override the
withdraw()
method inSavingsAccount
to include a withdrawal fee of 1% of the withdrawal amount. - Create instances of
BankAccount
andSavingsAccount
, and test thedeposit()
andwithdraw()
methods.
Solution:
class BankAccount:
def __init__(self):
self.balance = 0
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
if amount <= self.balance:
self.balance -= amount
else:
print("Insufficient funds")
class SavingsAccount(BankAccount):
def __init__(self, interest_rate):
super().__init__()
self.interest_rate = interest_rate
def withdraw(self, amount):
fee = amount * 0.01
if amount + fee <= self.balance:
self.balance -= (amount + fee)
else:
print("Insufficient funds")
account1 = BankAccount()
account1.deposit(100)
account1.withdraw(50)
print(account1.balance) # Output: 50
savings1 = SavingsAccount(0.02)
savings1.deposit(100)
savings1.withdraw(50)
print(savings1.balance) # Output: 49.5
Exercise 8.3.3: Multiple Inheritance
Implement a class hierarchy using multiple inheritance.
Instructions:
- Create a class
Person
with attributesfirst_name
andlast_name
. - Create a class
Employee
that inherits fromPerson
and has an additional attributeemployee_id
. - Create a class
Student
that inherits fromPerson
and has an additional attributestudent_id
. - Create a class
TeachingAssistant
that inherits from bothEmployee
andStudent
. - Define a method
get_info()
for each class that returns a string with the person's information. - Create an instance of
TeachingAssistant
and call theget_info()
method.
Solution:
class Person:
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def get_info(self):
return f"{self.first_name} {self.last_name}"
class Employee(Person):
def __init__(self, first_name, last_name, employee_id):
super().__init__(first_name, last_name)
self.employee_id = employee_id
def get_info(self):
return f"{super().get_info()}, Employee ID: {self.employee_id}"
class Student(Person):
def __init__(self, first_name, last_name, student_id):
super().__init__(first_name, last_name)
self.student_id = student_id
def get_info(self):
return f"{super().get_info()}, Student ID: {self.student_id}"
class TeachingAssistant(Employee, Student):
def __init__(self, first_name, last_name, employee_id, student_id):
Employee.__init__(self, first_name, last_name, employee_id)
Student.__init__(self, first_name, last_name, student_id)
def get_info(self):
return f"{super().get_info()}, Employee ID: {self.employee_id}, Student ID: {self.student_id}"
ta1 = TeachingAssistant("John", "Doe", 1001, 2001)
print(ta1.get_info()) # Output: John Doe, Employee ID: 1001, Student ID: 2001
8.3: Inheritance
Inheritance is one of the most powerful features in object-oriented programming, and it can greatly enhance the efficiency of your code. By allowing one class to inherit the attributes and methods of another class, you can create new classes that are built on top of existing ones, which can save a lot of time and effort.
For example, let's say you have a class that represents a car, with attributes like the make, model, and year, and methods like start_engine and accelerate. Now, let's say you want to create a new class for a specific type of car, like a sports car. Instead of starting from scratch and defining all of the attributes and methods for the sports car, you can simply create a new class that inherits from the car class, and then add or modify the attributes and methods as necessary. This way, you can reuse much of the code that you already wrote for the car class, and only focus on the changes that are specific to the sports car.
In Python, inheritance is implemented by defining a new class that takes the parent (base) class as an argument. The new class is called the child (derived) class, and the class it inherits from is called the parent (base) class. By using inheritance, you can create complex class hierarchies that can help you organize your code and make it more modular and reusable. Overall, inheritance is an essential concept in object-oriented programming, and mastering it can greatly improve your coding skills.
Let's understand inheritance through an example.
Suppose we have a base class called Animal
that represents a generic animal, with attributes like name
, age
, and a method called speak()
:
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def speak(self):
print(f"{self.name} makes a noise")
Now, we want to create a class Dog
that represents a dog, which is a specific type of animal. Instead of redefining all the attributes and methods of the Animal
class, we can inherit them using inheritance:
class Dog(Animal):
def __init__(self, name, age, breed):
super().__init__(name, age)
self.breed = breed
def speak(self):
print(f"{self.name} barks")
In this example, we define the Dog
class and inherit from the Animal
class. We use the super()
function to call the __init__
method of the parent class to initialize the name
and age
attributes. We also add a new attribute, breed
, specific to the Dog
class.
We also override the speak()
method of the Animal
class to better fit the behavior of a dog. This is called method overriding and is a common practice when using inheritance.
Now, when we create a Dog
object, it will have access to both the attributes and methods of the Animal
class, as well as any new attributes or methods we define in the Dog
class:
dog1 = Dog("Max", 3, "Labrador")
print(dog1.name) # Output: Max
print(dog1.age) # Output: 3
print(dog1.breed) # Output: Labrador
dog1.speak() # Output: Max barks
Inheritance is a fundamental concept in object-oriented programming that allows for the creation of more specialized classes. It enables code reuse from more general classes while providing the ability to customize or extend their behavior as needed. This makes inheritance a powerful tool for developers to create efficient and effective software solutions.
By using inheritance, developers can create a hierarchy of classes that share common characteristics, allowing for the implementation of complex systems. Additionally, inheritance helps reduce the complexity of code, making it easier to maintain and update over time. Therefore, it is essential to have a solid understanding of inheritance when developing software applications, as it can greatly improve the overall quality of the code and make it more scalable.
Exercise 8.3.1: Simple Inheritance
Implement a class hierarchy for different types of vehicles, using inheritance.
Instructions:
- Create a base class called
Vehicle
with attributesmake
,model
, andyear
. - Define a method
vehicle_info()
that prints the make, model, and year of the vehicle. - Create a class
Car
that inherits fromVehicle
and has an additional attributedoors
. - Create a class
Motorcycle
that inherits fromVehicle
and has an additional attributetype
. - Create instances of
Car
andMotorcycle
, and call thevehicle_info()
method for each.
Solution:
class Vehicle:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
def vehicle_info(self):
print(f"{self.year} {self.make} {self.model}")
class Car(Vehicle):
def __init__(self, make, model, year, doors):
super().__init__(make, model, year)
self.doors = doors
class Motorcycle(Vehicle):
def __init__(self, make, model, year, bike_type):
super().__init__(make, model, year)
self.type = bike_type
car1 = Car("Toyota", "Camry", 2020, 4)
car1.vehicle_info() # Output: 2020 Toyota Camry
motorcycle1 = Motorcycle("Yamaha", "R1", 2019, "Sport")
motorcycle1.vehicle_info() # Output: 2019 Yamaha R1
Exercise 8.3.2: Inheritance and Method Overriding
Create classes representing different types of bank accounts, using inheritance and method overriding.
Instructions:
- Create a base class
BankAccount
with attributesbalance
and a methoddeposit()
. - Define a method
withdraw()
that checks if the withdrawal amount is less than or equal to the balance, and updates the balance accordingly. - Create a class
SavingsAccount
that inherits fromBankAccount
and has an additional attributeinterest_rate
. - Override the
withdraw()
method inSavingsAccount
to include a withdrawal fee of 1% of the withdrawal amount. - Create instances of
BankAccount
andSavingsAccount
, and test thedeposit()
andwithdraw()
methods.
Solution:
class BankAccount:
def __init__(self):
self.balance = 0
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
if amount <= self.balance:
self.balance -= amount
else:
print("Insufficient funds")
class SavingsAccount(BankAccount):
def __init__(self, interest_rate):
super().__init__()
self.interest_rate = interest_rate
def withdraw(self, amount):
fee = amount * 0.01
if amount + fee <= self.balance:
self.balance -= (amount + fee)
else:
print("Insufficient funds")
account1 = BankAccount()
account1.deposit(100)
account1.withdraw(50)
print(account1.balance) # Output: 50
savings1 = SavingsAccount(0.02)
savings1.deposit(100)
savings1.withdraw(50)
print(savings1.balance) # Output: 49.5
Exercise 8.3.3: Multiple Inheritance
Implement a class hierarchy using multiple inheritance.
Instructions:
- Create a class
Person
with attributesfirst_name
andlast_name
. - Create a class
Employee
that inherits fromPerson
and has an additional attributeemployee_id
. - Create a class
Student
that inherits fromPerson
and has an additional attributestudent_id
. - Create a class
TeachingAssistant
that inherits from bothEmployee
andStudent
. - Define a method
get_info()
for each class that returns a string with the person's information. - Create an instance of
TeachingAssistant
and call theget_info()
method.
Solution:
class Person:
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def get_info(self):
return f"{self.first_name} {self.last_name}"
class Employee(Person):
def __init__(self, first_name, last_name, employee_id):
super().__init__(first_name, last_name)
self.employee_id = employee_id
def get_info(self):
return f"{super().get_info()}, Employee ID: {self.employee_id}"
class Student(Person):
def __init__(self, first_name, last_name, student_id):
super().__init__(first_name, last_name)
self.student_id = student_id
def get_info(self):
return f"{super().get_info()}, Student ID: {self.student_id}"
class TeachingAssistant(Employee, Student):
def __init__(self, first_name, last_name, employee_id, student_id):
Employee.__init__(self, first_name, last_name, employee_id)
Student.__init__(self, first_name, last_name, student_id)
def get_info(self):
return f"{super().get_info()}, Employee ID: {self.employee_id}, Student ID: {self.student_id}"
ta1 = TeachingAssistant("John", "Doe", 1001, 2001)
print(ta1.get_info()) # Output: John Doe, Employee ID: 1001, Student ID: 2001
8.3: Inheritance
Inheritance is one of the most powerful features in object-oriented programming, and it can greatly enhance the efficiency of your code. By allowing one class to inherit the attributes and methods of another class, you can create new classes that are built on top of existing ones, which can save a lot of time and effort.
For example, let's say you have a class that represents a car, with attributes like the make, model, and year, and methods like start_engine and accelerate. Now, let's say you want to create a new class for a specific type of car, like a sports car. Instead of starting from scratch and defining all of the attributes and methods for the sports car, you can simply create a new class that inherits from the car class, and then add or modify the attributes and methods as necessary. This way, you can reuse much of the code that you already wrote for the car class, and only focus on the changes that are specific to the sports car.
In Python, inheritance is implemented by defining a new class that takes the parent (base) class as an argument. The new class is called the child (derived) class, and the class it inherits from is called the parent (base) class. By using inheritance, you can create complex class hierarchies that can help you organize your code and make it more modular and reusable. Overall, inheritance is an essential concept in object-oriented programming, and mastering it can greatly improve your coding skills.
Let's understand inheritance through an example.
Suppose we have a base class called Animal
that represents a generic animal, with attributes like name
, age
, and a method called speak()
:
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def speak(self):
print(f"{self.name} makes a noise")
Now, we want to create a class Dog
that represents a dog, which is a specific type of animal. Instead of redefining all the attributes and methods of the Animal
class, we can inherit them using inheritance:
class Dog(Animal):
def __init__(self, name, age, breed):
super().__init__(name, age)
self.breed = breed
def speak(self):
print(f"{self.name} barks")
In this example, we define the Dog
class and inherit from the Animal
class. We use the super()
function to call the __init__
method of the parent class to initialize the name
and age
attributes. We also add a new attribute, breed
, specific to the Dog
class.
We also override the speak()
method of the Animal
class to better fit the behavior of a dog. This is called method overriding and is a common practice when using inheritance.
Now, when we create a Dog
object, it will have access to both the attributes and methods of the Animal
class, as well as any new attributes or methods we define in the Dog
class:
dog1 = Dog("Max", 3, "Labrador")
print(dog1.name) # Output: Max
print(dog1.age) # Output: 3
print(dog1.breed) # Output: Labrador
dog1.speak() # Output: Max barks
Inheritance is a fundamental concept in object-oriented programming that allows for the creation of more specialized classes. It enables code reuse from more general classes while providing the ability to customize or extend their behavior as needed. This makes inheritance a powerful tool for developers to create efficient and effective software solutions.
By using inheritance, developers can create a hierarchy of classes that share common characteristics, allowing for the implementation of complex systems. Additionally, inheritance helps reduce the complexity of code, making it easier to maintain and update over time. Therefore, it is essential to have a solid understanding of inheritance when developing software applications, as it can greatly improve the overall quality of the code and make it more scalable.
Exercise 8.3.1: Simple Inheritance
Implement a class hierarchy for different types of vehicles, using inheritance.
Instructions:
- Create a base class called
Vehicle
with attributesmake
,model
, andyear
. - Define a method
vehicle_info()
that prints the make, model, and year of the vehicle. - Create a class
Car
that inherits fromVehicle
and has an additional attributedoors
. - Create a class
Motorcycle
that inherits fromVehicle
and has an additional attributetype
. - Create instances of
Car
andMotorcycle
, and call thevehicle_info()
method for each.
Solution:
class Vehicle:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
def vehicle_info(self):
print(f"{self.year} {self.make} {self.model}")
class Car(Vehicle):
def __init__(self, make, model, year, doors):
super().__init__(make, model, year)
self.doors = doors
class Motorcycle(Vehicle):
def __init__(self, make, model, year, bike_type):
super().__init__(make, model, year)
self.type = bike_type
car1 = Car("Toyota", "Camry", 2020, 4)
car1.vehicle_info() # Output: 2020 Toyota Camry
motorcycle1 = Motorcycle("Yamaha", "R1", 2019, "Sport")
motorcycle1.vehicle_info() # Output: 2019 Yamaha R1
Exercise 8.3.2: Inheritance and Method Overriding
Create classes representing different types of bank accounts, using inheritance and method overriding.
Instructions:
- Create a base class
BankAccount
with attributesbalance
and a methoddeposit()
. - Define a method
withdraw()
that checks if the withdrawal amount is less than or equal to the balance, and updates the balance accordingly. - Create a class
SavingsAccount
that inherits fromBankAccount
and has an additional attributeinterest_rate
. - Override the
withdraw()
method inSavingsAccount
to include a withdrawal fee of 1% of the withdrawal amount. - Create instances of
BankAccount
andSavingsAccount
, and test thedeposit()
andwithdraw()
methods.
Solution:
class BankAccount:
def __init__(self):
self.balance = 0
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
if amount <= self.balance:
self.balance -= amount
else:
print("Insufficient funds")
class SavingsAccount(BankAccount):
def __init__(self, interest_rate):
super().__init__()
self.interest_rate = interest_rate
def withdraw(self, amount):
fee = amount * 0.01
if amount + fee <= self.balance:
self.balance -= (amount + fee)
else:
print("Insufficient funds")
account1 = BankAccount()
account1.deposit(100)
account1.withdraw(50)
print(account1.balance) # Output: 50
savings1 = SavingsAccount(0.02)
savings1.deposit(100)
savings1.withdraw(50)
print(savings1.balance) # Output: 49.5
Exercise 8.3.3: Multiple Inheritance
Implement a class hierarchy using multiple inheritance.
Instructions:
- Create a class
Person
with attributesfirst_name
andlast_name
. - Create a class
Employee
that inherits fromPerson
and has an additional attributeemployee_id
. - Create a class
Student
that inherits fromPerson
and has an additional attributestudent_id
. - Create a class
TeachingAssistant
that inherits from bothEmployee
andStudent
. - Define a method
get_info()
for each class that returns a string with the person's information. - Create an instance of
TeachingAssistant
and call theget_info()
method.
Solution:
class Person:
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def get_info(self):
return f"{self.first_name} {self.last_name}"
class Employee(Person):
def __init__(self, first_name, last_name, employee_id):
super().__init__(first_name, last_name)
self.employee_id = employee_id
def get_info(self):
return f"{super().get_info()}, Employee ID: {self.employee_id}"
class Student(Person):
def __init__(self, first_name, last_name, student_id):
super().__init__(first_name, last_name)
self.student_id = student_id
def get_info(self):
return f"{super().get_info()}, Student ID: {self.student_id}"
class TeachingAssistant(Employee, Student):
def __init__(self, first_name, last_name, employee_id, student_id):
Employee.__init__(self, first_name, last_name, employee_id)
Student.__init__(self, first_name, last_name, student_id)
def get_info(self):
return f"{super().get_info()}, Employee ID: {self.employee_id}, Student ID: {self.student_id}"
ta1 = TeachingAssistant("John", "Doe", 1001, 2001)
print(ta1.get_info()) # Output: John Doe, Employee ID: 1001, Student ID: 2001
8.3: Inheritance
Inheritance is one of the most powerful features in object-oriented programming, and it can greatly enhance the efficiency of your code. By allowing one class to inherit the attributes and methods of another class, you can create new classes that are built on top of existing ones, which can save a lot of time and effort.
For example, let's say you have a class that represents a car, with attributes like the make, model, and year, and methods like start_engine and accelerate. Now, let's say you want to create a new class for a specific type of car, like a sports car. Instead of starting from scratch and defining all of the attributes and methods for the sports car, you can simply create a new class that inherits from the car class, and then add or modify the attributes and methods as necessary. This way, you can reuse much of the code that you already wrote for the car class, and only focus on the changes that are specific to the sports car.
In Python, inheritance is implemented by defining a new class that takes the parent (base) class as an argument. The new class is called the child (derived) class, and the class it inherits from is called the parent (base) class. By using inheritance, you can create complex class hierarchies that can help you organize your code and make it more modular and reusable. Overall, inheritance is an essential concept in object-oriented programming, and mastering it can greatly improve your coding skills.
Let's understand inheritance through an example.
Suppose we have a base class called Animal
that represents a generic animal, with attributes like name
, age
, and a method called speak()
:
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def speak(self):
print(f"{self.name} makes a noise")
Now, we want to create a class Dog
that represents a dog, which is a specific type of animal. Instead of redefining all the attributes and methods of the Animal
class, we can inherit them using inheritance:
class Dog(Animal):
def __init__(self, name, age, breed):
super().__init__(name, age)
self.breed = breed
def speak(self):
print(f"{self.name} barks")
In this example, we define the Dog
class and inherit from the Animal
class. We use the super()
function to call the __init__
method of the parent class to initialize the name
and age
attributes. We also add a new attribute, breed
, specific to the Dog
class.
We also override the speak()
method of the Animal
class to better fit the behavior of a dog. This is called method overriding and is a common practice when using inheritance.
Now, when we create a Dog
object, it will have access to both the attributes and methods of the Animal
class, as well as any new attributes or methods we define in the Dog
class:
dog1 = Dog("Max", 3, "Labrador")
print(dog1.name) # Output: Max
print(dog1.age) # Output: 3
print(dog1.breed) # Output: Labrador
dog1.speak() # Output: Max barks
Inheritance is a fundamental concept in object-oriented programming that allows for the creation of more specialized classes. It enables code reuse from more general classes while providing the ability to customize or extend their behavior as needed. This makes inheritance a powerful tool for developers to create efficient and effective software solutions.
By using inheritance, developers can create a hierarchy of classes that share common characteristics, allowing for the implementation of complex systems. Additionally, inheritance helps reduce the complexity of code, making it easier to maintain and update over time. Therefore, it is essential to have a solid understanding of inheritance when developing software applications, as it can greatly improve the overall quality of the code and make it more scalable.
Exercise 8.3.1: Simple Inheritance
Implement a class hierarchy for different types of vehicles, using inheritance.
Instructions:
- Create a base class called
Vehicle
with attributesmake
,model
, andyear
. - Define a method
vehicle_info()
that prints the make, model, and year of the vehicle. - Create a class
Car
that inherits fromVehicle
and has an additional attributedoors
. - Create a class
Motorcycle
that inherits fromVehicle
and has an additional attributetype
. - Create instances of
Car
andMotorcycle
, and call thevehicle_info()
method for each.
Solution:
class Vehicle:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
def vehicle_info(self):
print(f"{self.year} {self.make} {self.model}")
class Car(Vehicle):
def __init__(self, make, model, year, doors):
super().__init__(make, model, year)
self.doors = doors
class Motorcycle(Vehicle):
def __init__(self, make, model, year, bike_type):
super().__init__(make, model, year)
self.type = bike_type
car1 = Car("Toyota", "Camry", 2020, 4)
car1.vehicle_info() # Output: 2020 Toyota Camry
motorcycle1 = Motorcycle("Yamaha", "R1", 2019, "Sport")
motorcycle1.vehicle_info() # Output: 2019 Yamaha R1
Exercise 8.3.2: Inheritance and Method Overriding
Create classes representing different types of bank accounts, using inheritance and method overriding.
Instructions:
- Create a base class
BankAccount
with attributesbalance
and a methoddeposit()
. - Define a method
withdraw()
that checks if the withdrawal amount is less than or equal to the balance, and updates the balance accordingly. - Create a class
SavingsAccount
that inherits fromBankAccount
and has an additional attributeinterest_rate
. - Override the
withdraw()
method inSavingsAccount
to include a withdrawal fee of 1% of the withdrawal amount. - Create instances of
BankAccount
andSavingsAccount
, and test thedeposit()
andwithdraw()
methods.
Solution:
class BankAccount:
def __init__(self):
self.balance = 0
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
if amount <= self.balance:
self.balance -= amount
else:
print("Insufficient funds")
class SavingsAccount(BankAccount):
def __init__(self, interest_rate):
super().__init__()
self.interest_rate = interest_rate
def withdraw(self, amount):
fee = amount * 0.01
if amount + fee <= self.balance:
self.balance -= (amount + fee)
else:
print("Insufficient funds")
account1 = BankAccount()
account1.deposit(100)
account1.withdraw(50)
print(account1.balance) # Output: 50
savings1 = SavingsAccount(0.02)
savings1.deposit(100)
savings1.withdraw(50)
print(savings1.balance) # Output: 49.5
Exercise 8.3.3: Multiple Inheritance
Implement a class hierarchy using multiple inheritance.
Instructions:
- Create a class
Person
with attributesfirst_name
andlast_name
. - Create a class
Employee
that inherits fromPerson
and has an additional attributeemployee_id
. - Create a class
Student
that inherits fromPerson
and has an additional attributestudent_id
. - Create a class
TeachingAssistant
that inherits from bothEmployee
andStudent
. - Define a method
get_info()
for each class that returns a string with the person's information. - Create an instance of
TeachingAssistant
and call theget_info()
method.
Solution:
class Person:
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def get_info(self):
return f"{self.first_name} {self.last_name}"
class Employee(Person):
def __init__(self, first_name, last_name, employee_id):
super().__init__(first_name, last_name)
self.employee_id = employee_id
def get_info(self):
return f"{super().get_info()}, Employee ID: {self.employee_id}"
class Student(Person):
def __init__(self, first_name, last_name, student_id):
super().__init__(first_name, last_name)
self.student_id = student_id
def get_info(self):
return f"{super().get_info()}, Student ID: {self.student_id}"
class TeachingAssistant(Employee, Student):
def __init__(self, first_name, last_name, employee_id, student_id):
Employee.__init__(self, first_name, last_name, employee_id)
Student.__init__(self, first_name, last_name, student_id)
def get_info(self):
return f"{super().get_info()}, Employee ID: {self.employee_id}, Student ID: {self.student_id}"
ta1 = TeachingAssistant("John", "Doe", 1001, 2001)
print(ta1.get_info()) # Output: John Doe, Employee ID: 1001, Student ID: 2001