Introduction to Object Oriented Programming: Classes and Objects

What are Classes?

Classes are blueprints for representing various real wold things and situations. They are models from which various objects can be constructed.

Object Oriented Programming

What are Objects?

Objects are instances of classes. They are automatically equipped with the behaviour(attributes and methods) of the classes from which they are constructed.

The process of making an object from a class is called instantiation.

Classes make your code well organized, easily maintainable and readable. They also allow other programmers to collaborate with your work easily.

Creating a Class

The first line contains the class keyword followed by the class name and an optional parenthesis which is followed by a colon.

The subsequent line should be the __init__() method. This method runs automatically when an object is created from a class.

The __init__() method requires a compulsory self parameter as its first parameter. The self parameter can then be followed by any amount of parameters to suit your need.

These parameters are also called attributes. They are what differentiate objects from each other.

Let’s create a Car class. The attributes for a car can be the brand, model and year.

class Car():
    def __init__(self,brand,model,year):
        """initializing attributes"""
        self.brand = brand
        self.model = model
        self.year = year

These attributes are then initialized in the __init__() method. This way, it is easy to access and modify each attribute value of an object.

The self dot notation (e.g self.model) signifies that attributes are unique to their respective objects.

Having created a Car class, let’s create an object or instance of this class.

first_car = Car('toyota','camry',2020)

As shown above, the brand, model and year arguments are the only required arguments. Python automatically fills in the self argument.

Accessing Attribute Values

To access each attribute’s value, you only need to use the dot syntax as shown below.

#accessing attributes
print(first_car.brand)
print(first_car.model)
print(first_car.year)

accessing class attributes

Modifying Attribute Values

To modify an attribute value, you only need access the attribute and reassign a new value to it as shown below.

#modifying an attribute
first_car.year = 2018

#accessing the modified attribute
print(first_car.year)

modifying class attributes

Methods

However, there’s more to a car than its attributes. The functions of the car.

A car can drive, reverse and park among other numerous functions. For simplicity, we’ll only create drive, reverse and park methods for this Car class.

A method is a function particular to a class. This implies that a method cannot be used outside the scope of a class. It can only be used or accessed by instances or objects of the class.

We created a method earlier. The __init__() method.

Let’s modify the previous Car class to include drive, reverse and park methods.

class Car():
    def __init__(self,brand,model,year):
        """initializing attributes"""    
        self.brand = brand
        self.model = model
        self.year = year

    def drive(self):
        print(f'{self.brand} {self.model} is driving')

    def reverse(self):
        print(f'{self.brand} {self.model} is reversing')

    def park(self):
        print(f'{self.brand} {self.model} is parking')

As shown above, the self parameter is also required as the first parameter in defining a method.

These methods only print a simple message when called. Building a real car model would require more than these but the concept is quite similar.

Calling Methods

The dot syntax is used in calling methods with the parenthesis at the end as shown below.

#reconstructing the object
first_car = Car('toyota','camry',2020)

#calling methods
first_car.drive()
first_car.reverse()
first_car.park()

calling methods

Whenever you make changes to a class, ensure to reconstruct its objects.

Let’s add another method that would require an argument when called.

class Car():
    def __init__(self,brand,model,year):
        """initializing attributes"""
        self.brand = brand
        self.model = model
        self.year = year

    def drive(self):
        print(f'{self.brand} {self.model} is driving')

    def reverse(self):
        print(f'{self.brand} {self.model} is reversing')

    def park(self):
        print(f'{self.brand} {self.model} is parking')
    
    def fill_tank(self,volume):
        print(f'{self.brand} {self.model} is being filled with {volume} litres of fuel')

#reconstructing the object
first_car = Car('toyota','camry',2020)

#calling a method with an argument
first_car.fill_tank(30)

calling methods

Inheritance

You don’t need to write every class from the scratch. If the class you’re writing has some similarities with an existing class, you can use inheritance. Your new class inherits from the existing class.

Let’s create an ElectricCar class. This would inherit from our previously written Car class.

The class from which our new class would inherit from is put in the parenthesis.

The __init__() method includes a line of code to initialize attributes of the parent class. The parent class in this scenario is the Car class while the ElectricCar class is a child class.

class ElectricCar(Car):
    def __init__(self,brand,model,year,battery):
        """initializing attributes"""
        super().__init__(brand,model,year)
        self.battery = battery

super.__init__() initializes the attributes of the Car class which makes them accessible by the ElectricCar class.

There’s an additional parameter for the ElectricCar class, battery, which was initialized manually (self.battery = battery).

Notice how the __init__() method was supplied with the brand, model and class argument. This is because it is not automatically called from a child class.

The ElectricCar class has automatically inherited the methods of the parent class too.

Let’s create an object from the ElectricCar class and access these attributes and methods

#creating an electric car object
second_car = ElectricCar('bmw','i3',2019,'42-kWh')

#accessing attributes
print(second_car.brand)
print(second_car.battery)

#calling methods
second_car.drive()
second_car.park()

accessing attributes and methods

Modifying Methods From a Child Class

An electric car does not have a fuel tank. We can modify the fill_tank() method to print a different message by redefining the method as shown below.

class ElectricCar(Car):
    def __init__(self,brand,model,year,battery):
        """initializing attributes"""
        super().__init__(brand,model,year)
        self.battery = battery

    def fill_tank(self):
        print(f'{self.brand} {self.model} can only be recharged')

#reconstructing the object
second_car = ElectricCar('bmw','i3',2019,'42-kWh')

#calling the fill tank method
second_car.fill_tank()

modifying methods from a child class

Since the electric car has a battery, let’s define a method to recharge it.

class ElectricCar(Car):
    def __init__(self,brand,model,year,battery):
        """initializing attributes"""
        super().__init__(brand,model,year)
        self.battery = battery

    def fill_tank(self):
        print(f'{self.brand} {self.model} can only be recharged')

    def recharge(self):
        print(f'{self.brand} {self.model} is recharging')

#reconstructing the object
second_car = ElectricCar('bmw','i3',2019,'42-kWh')

#calling the recharge method
second_car.recharge()

class methods

Summary

  • Various real world situations can be represented with classes
  • Methods are functions particular to classes
  • Classes can inherit from existing classes with similarities
  • Attributes and Methods can be modified by Child classes

No comments:

Powered by Blogger.