Class 1: Object-Oriented Programming
Object-oriented programming (OOP) is a programming paradigm that focuses on creating objects that encapsulate data and methods, and interact with each other to accomplish tasks. In OOP, data and functions are bundled together into objects, allowing for modular, reusable, and organized code.
Review of basic concepts of OOP:
- Encapsulation: Encapsulation is the concept of bundling data and methods that work on that data within one unit. This is typically achieved in OOP by defining classes, which contain attributes (data) and methods (functions).
- Inheritance: Inheritance is a mechanism for creating a new class that is a modified version of an existing class. The new class inherits all the attributes and methods of the original class and can then add or modify its own.
- Polymorphism: Polymorphism is the ability of an object to take on many forms. In OOP, this is achieved through inheritance and method overriding.
Defining classes in Python:
In Python, a class is defined using the class
keyword followed by the class name. The class body contains attributes and methods that define the behavior of the class.
class Employee:
def __init__(self, name, salary):
self.name = name
self.salary = salary
def get_salary(self):
return self.salary
In this example, we define a class called Employee
that has two attributes (name
and salary
) and one method (get_salary
). The __init__
method is a special method that is called when an instance of the class is created, and is used to initialize the attributes of the class.
Creating objects and invoking methods:
Once a class is defined, we can create instances of the class, also known as objects, using the class constructor. We can then call methods on the objects to perform tasks.
employee1 = Employee("John Doe", 50000)
print(employee1.get_salary())
In this example, we create an instance of the Employee
class called employee1
with a name of "John Doe" and a salary of 50000. We then call the get_salary
method on employee1
and print the result.
Inheritance and polymorphism:
Inheritance is a mechanism for creating a new class that is a modified version of an existing class. In Python, we can define a subclass by passing the parent class as a parameter to the class
keyword.
class Manager(Employee):
def __init__(self, name, salary, bonus):
super().__init__(name, salary)
self.bonus = bonus
def get_salary(self):
return self.salary + self.bonus
In this example, we define a Manager
class that is a subclass of the Employee
class. The Manager
class has an additional attribute (bonus
) and a modified get_salary
method that adds the bonus to the base salary.
We can now create instances of both the Employee
and Manager
classes, and call their respective methods.
employee1 = Employee("John Doe", 50000)
manager1 = Manager("Jane Smith", 75000, 10000)
print(employee1.get_salary())
print(manager1.get_salary())
This will output:
Exercise 1:
Creating a Bank Account Class
In this exercise, you will create a Bank Account class that allows you to perform basic operations such as depositing money, withdrawing money, and checking the account balance.
- Define a BankAccount class with the following attributes:
- account_number (string)
- account_holder (string)
- balance (float)
2. Define the init method of the BankAccount class that initializes the above attributes with default values.
3. Define methods to perform the following operations:
- deposit(amount): Add the amount to the account balance.
- withdraw(amount): Subtract the amount from the account balance. Make sure the balance is not negative after the withdrawal.
- check_balance(): Return the current account balance.
4. Create an instance of the BankAccount class and test the methods.
Example code:
class BankAccount:
def __init__(self, account_number="000000", account_holder="John Doe", balance=0.0):
self.account_number = account_number
self.account_holder = account_holder
self.balance = balance
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
if self.balance - amount < 0:
print("Insufficient funds")
else:
self.balance -= amount
def check_balance(self):
return self.balance
account1 = BankAccount("123456", "Alice", 1000.0)
print("Initial balance:", account1.check_balance())
account1.deposit(500.0)
print("Balance after deposit:", account1.check_balance())
account1.withdraw(2000.0)
print("Balance after withdrawal:", account1.check_balance())
Exercise 2: Inheritance and Polymorphism
In this exercise, you will create a hierarchy of classes to model different types of vehicles.
- Define a Vehicle class with the following attributes:
- make (string)
- model (string)
- year (integer)
- weight (float)
2. Define the init method of the Vehicle class that initializes the above attributes with default values.
3. Define methods to perform the following operations:
- get_make(): Return the make of the vehicle.
- get_model(): Return the model of the vehicle.
- get_year(): Return the year of the vehicle.
- get_weight(): Return the weight of the vehicle.
4. Create a Car class that inherits from the Vehicle class and adds the following attributes:
- num_doors (integer)
- num_passengers (integer)
5. Define the init method of the Car class that initializes the above attributes with default values.
6. Define methods to perform the following operations:
- get_num_doors(): Return the number of doors of the car.
- get_num_passengers(): Return the number of passengers that can fit in the car.
7. Create a Truck class that inherits from the Vehicle class and adds the following attributes:
- payload_capacity (float)
8. Define the init method of the Truck class that initializes the above attributes with default values.
9. Define methods to perform the following operations:
- get_payload_capacity(): Return the payload capacity of the truck.
10. Create a Motorcycle class that inherits from the Vehicle class and adds the following attributes:
- num_wheels (integer)
- has_sidecar (boolean)
11. Define the init method of the Motorcycle class that initializes the above attributes with default values.
12. Define methods to perform the following operations:
- get_num_wheels(): Return the number of wheels of the motorcycle.
- has_sidecar(): Return whether the motorcycle has a sidecar or not.
13. Create instances of the Car, Truck, and Motorcycle classes and test the methods.
class Vehicle:
def __init__(self, make='Unknown', model='Unknown', year=0, weight=0.0):
self.make = make
self.model = model
self.year = year
self.weight = weight
def get_make(self):
return self.make
def get_model(self):
return self.model
def get_year(self):
return self.year
def get_weight(self):
return self.weight
class Car(Vehicle):
def __init__(self, make='Unknown', model='Unknown', year=0, weight=0.0, num_doors=4, num_passengers=5):
super().__init__(make, model, year, weight)
self.num_doors = num_doors
self.num_passengers = num_passengers
def get_num_doors(self):
return self.num_doors
def get_num_passengers(self):
return self.num_passengers
class Truck(Vehicle):
def __init__(self, make='Unknown', model='Unknown', year=0, weight=0.0, payload_capacity=0.0):
super().__init__(make, model, year, weight)
self.payload_capacity = payload_capacity
def get_payload_capacity(self):
return self.payload_capacity
class Motorcycle(Vehicle):
def __init__(self, make='Unknown', model='Unknown', year=0, weight=0.0, num_wheels=2, has_sidecar=False):
super().__init__(make, model, year, weight)
self.num_wheels = num_wheels
self.has_sidecar = has_sidecar
def get_num_wheels(self):
return self.num_wheels
def has_sidecar(self):
return self.has_sidecar
# create instances of Car, Truck, and Motorcycle classes
car1 = Car(make='Toyota', model='Corolla', year=2015, weight=3000.0, num_doors=4, num_passengers=5)
truck1 = Truck(make='Ford', model='F150', year=2020, weight=5000.0, payload_capacity=2000.0)
motorcycle1 = Motorcycle(make='Harley-Davidson', model='Street 750', year=2019, weight=500.0, num_wheels=2, has_sidecar=False)
# test the methods
print(car1.get_make()) # Toyota
print(truck1.get_year()) # 2020
print(motorcycle1.has_sidecar) # False