0% found this document useful (0 votes)
0 views

OO Python-Module 1 (1)

The document provides an overview of Object-Oriented Programming (OOP) concepts in Python, including classes, objects, methods, inheritance, polymorphism, encapsulation, and abstraction. It explains the differences between procedural and object-oriented programming, discusses constructors, and details various types of methods such as instance, class, and static methods. Additionally, it covers namespaces, encapsulation, and how to pass members between classes, emphasizing the importance of modular and reusable code.

Uploaded by

ashutosh.wk.24
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
0 views

OO Python-Module 1 (1)

The document provides an overview of Object-Oriented Programming (OOP) concepts in Python, including classes, objects, methods, inheritance, polymorphism, encapsulation, and abstraction. It explains the differences between procedural and object-oriented programming, discusses constructors, and details various types of methods such as instance, class, and static methods. Additionally, it covers namespaces, encapsulation, and how to pass members between classes, emphasizing the importance of modular and reusable code.

Uploaded by

ashutosh.wk.24
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

Mastering Object-Oriented Concepts in

Python

1|Page
Introduction to OOPS, Methods
Object-Oriented Programming Concepts in Python
Python is also an object-oriented language since its beginning. It allows us to develop applications
using an Object-Oriented approach. In Python, we can easily create and use classes and objects.

An object-oriented paradigm is to design the program using classes and objects. The object is related to
real-word entities such as book, house, pencil, etc. The oops concept focuses on writing the reusable code.
It is a widespread technique to solve the problem by creating objects.

Major principles of object-oriented programming system are given below.

o Class
o Object
o Method
o Inheritance
o Polymorphism
o Data Abstraction
o Encapsulation

Procedural vs. Object Oriented Programming

Procedural based programming is derived from structural programming based on the concepts of
functions/procedure/routines. It is easy to access and change the data in procedural oriented
programming. On the other hand, Object Oriented Programming (OOP) allows decomposition of a problem
into a number of units called objects and then build the data and functions around these objects. It emphasis
more on the data than procedure or functions. Also in OOP, data is hidden and cannot be accessed by
external procedure.

Class

The class can be defined as a collection of objects. It is a logical entity that has some specific
attributes and methods. For example: if you have a Car as a class, then it should contain an attribute and
method, i.e. an email model, price, colour and build year etc.

2|Page
In the above example, Car as a class, with main attributes such as model, price, color, and build year. We
can create as many objects we want from the class.

Sample Python Code

1. class car:
2. def __init__(self, model, price, color):
3. # This is the constructor method that is called when creating a new Car object
4. # It takes three parameters, model, price, color and initializes them as attributes of the object
5. self.model = model
6. self.price = price
7. self.colr = color
8. def car_details(self):
9. # This is a method of the Person class that prints a greeting message
10. print(" Model " + self.model)
11. print(" Price " + self.price)
12. print(" Color " + self.color)

Object

The object is an entity that has state and behavior. It may be any real-world object like the mouse,
keyboard, chair, table, pen, etc.

Everything in Python is an object, and almost everything has attributes and methods.

Attributes: Methods, Instance Variables, and Class Variables

 A method is a function you invoke on an instance of the class or the class itself.
 A method that is invoked on an instance is sometimes called an instance method.
 You can also invoke a method directly on a class, in which case it is called a class method or
a static method.

3|Page
 Attributes that take data values on a per-instance basis are frequently referred to as
instance variables.
 Attributes that take on values on a per-class basis are called class attributes or static
attributes or class variables.

Constructors

A constructor is a special type of method (function) which is used to initialize the instance members of the
class.

Constructor has the same name as its class in Python. It is used to create an object.

Constructors can be of two types.

1. Parameterized Constructor
2. Non-parameterized Constructor

Constructor definition is executed when we create the object of this class. Constructors also verify that there
are enough resources for the object to perform any start-up task.

Creating the constructor in python

In Python, the method the __init__() simulates the constructor of the class. This method is called
when the class is instantiated. It accepts the self-keyword as a first argument which allows accessing the
attributes or method of the class.

We can pass any number of arguments at the time of creating the class object, depending upon
the __init__() definition. It is mostly used to initialize the class attributes. Every class must have a constructor,
even if it simply relies on the default constructor.

Consider the following example to initialize the Employee class attributes.

class car:
def __init__( self, model, price, color):
self.model = model
self.price = price
self.color=color

def car_details(self):
print(" Model " + self.model)
print(" Price " + self.price)
print(" Color " + self.color)

car1 = car("BMW", 15000000, “Red”)


car2 = Employee("Benz”, 30000000, “Black”)

4|Page
# accessing car_details() method to print car1 & car2 information

car1. car_details ()
car2. car_details ()

Python Non-Parameterized Constructor

The non-parameterized constructor uses when we do not want to manipulate the value or the
constructor that has only self as an argument. Consider the following example.

Example
1. class Student:
2. # Constructor - non parameterized
3. def __init__(self):
4. print("This is non parametrized constructor")
5. def show(self,name):
6. print("Hello",name)
7. student = Student()
8. student.show("John")
Python Parameterized Constructor

The parameterized constructor has multiple parameters along with the self. Consider the following example.

Example
1. class Student:
2. # Constructor - parameterized
3. def __init__(self, name):
4. print("This is parametrized constructor")
5. self.name = name
6. def show(self):
7. print("Hello",self.name)
8. student = Student("John")
9. student.show()

Output:

This is parametrized constructor


Hello John

Python Default Constructor

When we do not include the constructor in the class or forget to declare it, then that becomes the
default constructor. It does not perform any task but initializes the objects. Consider the following example.

5|Page
Example
1. class Student:
2. roll_num = 101
3. name = "Scott"
4. def display(self):
5. print(self.roll_num,self.name)
6.
7. st = Student()
8. st.display()

Output:

101 Scott

Types of Methods: Instance Method, Class Method, Static Method,

In Object-oriented programming, when we design a class, we use the following three methods

 Instance method performs a set of actions on the data/value provided by the instance variables. If
we use instance variables inside a method, such methods are called instance methods.
 Class method is method that is called on the class itself, not on a specific object instance. Therefore,
it belongs to a class level, and all class instances share a class method.
 Static method is a general utility method that performs a task in isolation. This method doesn’t
have access to the instance and class variable.

Instance methods:

Instance methods are the most common type of methods in Python. They operate on instances of
the class (i.e., objects) and can access or modify the instance's attributes.

Constructor Relation**: The `__init__()` method itself is an instance method, used to initialize instance
attributes. Defined with the `self` parameter, which represents the instance calling the method.

6|Page
Example:

class Car:

def __init__(self, brand, model): # Constructor (instance method)

self.brand = brand

self.model = model

def display_info(self): # Instance method

print(f"Car: {self.brand} {self.model}")

car = Car('Toyota', 'Corolla')

car.display_info()

Output: Car: Toyota Corolla

Class methods:

Class methods are methods that operate on the class itself, rather than on instances of the class. They are
defined using the `@classmethod` decorator.

Constructor Relation: They are not typically used within constructors but can be used to manipulate
class-level data that applies to all instances.

Example:

class Car:

number_of_cars = 0 # Class attribute

def __init__(self, brand, model):

self.brand = brand

self.model = model

Car.number_of_cars += 1

@classmethod

def total_cars(cls): # Class method

print(f"Total cars created: {cls.number_of_cars}")

car1 = Car('Toyota', 'Corolla')

car2 = Car('Honda', 'Civic')

Car.total_cars()

Output: Total cars created: 2

7|Page
Static methods:

Static methods do not operate on an instance or class directly. They are defined using the
`@staticmethod` decorator and do not take `self` or `cls` as the first parameter.

Constructor Relation: Static methods are independent and do not relate directly to constructors but can be
used in the class for utility functions.

Usage: Ideal for utility or helper functions that do not need to access or modify class or instance data.

Example:

class MathOperations:

def __init__(self, value):

self.value = value

@staticmethod

def add(a, b): # Static method

return a + b

result = MathOperations.add(5, 3) # Calling static method

print(f"Addition result: {result}")

Output: Addition result: 8

Namespaces

In Python, a namespace** is like a container that holds the names of variables, functions, classes,
and other objects. It keeps track of all the identifiers (names) and their corresponding objects. This helps in
organizing the code and avoiding naming conflicts.

Simple Definition:

- A **namespace** is a collection of names mapped to objects. It helps in avoiding conflicts by ensuring


that each name is unique within a particular context.

Types of Namespaces:

1. **Local Namespace:** Contains names defined inside a function.

2. **Global Namespace:** Contains names defined at the top level of a script or module.

3. **Built-in Namespace:** Contains built-in functions and exceptions (like `print`, `len`, etc.).

Example:

Here's a simple example to demonstrate namespaces:

# Global namespace

x = 10 # This variable is in the global namespace

def my_function():

8|Page
# Local namespace

x = 20 # This variable is in the local namespace of the function

print("Inside function:", x) # Prints the local variable

# Calling the function

my_function()

# Accessing the global variable

print("Outside function:", x)

Output:

Inside function: 20

Outside function: 10

Here,

Inside the function, `x = 20` refers to the local namespace, so it prints `20`.

Outside the function, `x = 10` refers to the global namespace, so it prints `10`.

This separation prevents the local variable inside the function from interfering with the global variable
outside the function.

Encapsulation:

 Definition: Encapsulation is the concept of bundling the data (variables) and methods (functions)
that operate on the data into a single unit, like a class. It restricts direct access to some of an object’s
components, which means the internal representation of an object is hidden from the outside.
 Example: Using private variables and methods by prefixing them with an underscore _

Sample Code:

class Car:

def __init__(self, make, model):

self.make = make

self.model = model

self._engine_status = 'off' # Private variable

def start_engine(self):

self._engine_status = 'on' # Encapsulated method

def get_engine_status(self):

return self._engine_status

9|Page
car = Car('Toyota', 'Camry')

car.start_engine()

print(car.get_engine_status())

Output:

on

Abstraction:

 Definition: Abstraction is the concept of hiding complex implementation details and showing only
the essential features of an object. It helps to reduce complexity and allows the programmer to focus
on interactions at a higher level.
 Example: Using methods that show what an object does without revealing how it does it.

Sample Code:

from abc import ABC, abstractmethod

class Vehicle(ABC):

@abstractmethod

def start(self):

pass

class Bike(Vehicle):

def start(self):

print("Bike starting with a kick.")

class Car(Vehicle):

def start(self):

print("Car starting with a key.")

bike = Bike()

car = Car()

The _engine_status variable is encapsulated inside the class, and you interact with it through methods, not
directly.

The Vehicle class provides an abstract idea of starting a vehicle, but the actual implementation
(start()) is provided by the subclasses (Bike and Car). This hides the complex details of how each vehicle
starts.

10 | P a g e
Passing Members of One Class to Another Class

We can pass the members of one class to another class using objects in python. This allows sharing
functionality between different classes.

Passing members of one class to another class in Python involves using an instance of one class as
an attribute in another class. This approach is part of object composition, where a class is composed of
one or more objects from other classes, allowing for modular and reusable code.

Example:

Passing Members of One Class to Another Class

To demonstrate, let's create two classes: `Engine` and `Car`. The `Car` class will use an instance of the
`Engine` class as one of its members.

How to pass the member?

1. **Create the First Class (`Engine`):

- This class will have attributes and methods related to an engine.

2. **Create the Second Class (`Car`):

- This class will use an instance of the `Engine` class as a member to represent the car's engine.

Example Code

1. Class `Engine`:

- Defines an engine with a specific horsepower.

2. Class `Car`:

- Takes an `Engine` object as a parameter in its constructor and uses it to access engine-specific data.

# First Class: Engine

class Engine:

def __init__(self, horsepower):

self.horsepower = horsepower

def start(self):

print(f"Engine with {self.horsepower} HP started.")

# Second Class: Car

class Car:

def __init__(self, brand, model, engine):

self.brand = brand

self.model = model

self.engine = engine # Passing an instance of Engine class as a member

11 | P a g e
def display_info(self):

print(f"Car: {self.brand} {self.model} with {self.engine.horsepower} HP engine.")

def start_car(self):

print(f"Starting the car {self.brand} {self.model}.")

self.engine.start() # Using the Engine object's method

# Creating an object of the Engine class

engine = Engine(150)

# Passing the Engine object to the Car class

car = Car("Toyota", "Corolla", engine)

# Using methods of the Car class, which internally uses the Engine object

car.display_info() # Output: Car: Toyota Corolla with 150 HP engine.

car.start_car() # Output: Starting the car Toyota Corolla.

# Engine with 150 HP started.

Points to ponder:

1. Object Composition:

- The `Car` class uses an instance of the `Engine` class as an attribute, demonstrating object composition.

- This approach allows the `Car` class to utilize the functionality of the `Engine` class without inheritance.

2. Passing Objects:

- In the `Car` class constructor, `engine` is an instance of the `Engine` class passed as an argument.

- The `Car` class can access the `Engine` class's methods and attributes through this instance.

3. Modularity and Reusability:

- The `Engine` class can be used by other classes (e.g., `Truck`, `Boat`), enhancing code reusability and
modularity.

This pattern is useful in scenarios where classes represent complex entities composed of multiple,
independently defined components. By passing members from one class to another, you create flexible,
maintainable, and modular code structures in Python.

12 | P a g e
Create a Parent Class and Child Class

A parent class (or base class) is the class being inherited from. It provides common attributes and
methods that can be reused by child classes.

Creating a Parent Class and a Child Class in Python involves using inheritance, which allows one class (the
child) to inherit attributes and methods from another class (the parent). This is a fundamental concept in
object-oriented programming that promotes code reuse and organization.

Parent Class: The class whose properties and methods are inherited by another class. It is also known as
the base class or superclass.

Child Class: The class that inherits from the parent class. It can use and override the properties and
methods of the parent class. It is also known as the derived class or subclass.

Example: Creating a Parent Class and Child Class

Step 1: Define the Parent Class

- Use the `class` keyword followed by the class name.

- Define the constructor and any methods needed by the parent class.

Step 2: Define the Child Class

- Use the `class` keyword followed by the child class name. Specify the parent class in parentheses.

- The child class can inherit all the attributes & methods from the parent class and can also define its own.

Example Code

1. Parent Class: Animal

- This class defines basic attributes and a method for animals.

2. Child Class: Dog

- Inherits from the `Animal` class and adds its own specific method.

# Parent Class

class Animal:

def __init__(self, name, species):

self.name = name

self.species = species

def make_sound(self):

print(f"{self.name} makes a sound.")

# Child Class

class Dog(Animal): # Inheriting from Animal

def __init__(self, name, breed):

super().__init__(name, species="Dog") # Calling the parent class constructor

self.breed = breed

13 | P a g e
def make_sound(self): # Overriding the parent class method

print(f"{self.name} barks!")

def fetch(self):

print(f"{self.name} is fetching the ball.")

# Creating an object of the Parent class

generic_animal = Animal("Generic Animal", "Unknown Species")

generic_animal.make_sound() # Output: Generic Animal makes a sound.

# Creating an object of the Child class

dog = Dog("Buddy", "Golden Retriever")

dog.make_sound() # Output: Buddy barks!

dog.fetch() # Output: Buddy is fetching the ball.

Key Points

1. Inheritance: The `Dog` class inherits from the `Animal` class using `class Dog(Animal)`.

2. Constructor (`__init__`) in Child Class:

- The child class can use the parent class's constructor by calling `super().__init__()`.

- `super()` is a function used to refer to the parent class, allowing access to its methods.

3. Overriding Methods:

- The `Dog` class overrides the `make_sound()` method from the `Animal` class to provide specific
behavior for dogs.

4. **Additional Methods in Child Class**:

- The `Dog` class adds a new method `fetch()` that is not present in the `Animal` class.

This setup allows the `Dog` class to use and extend the functionality of the `Animal` class,
demonstrating the basics of inheritance in Python. If you need further clarifications or more examples, feel
free to ask!

A child class inherits the attributes and methods of a parent class. Inheritance allows code reusability and
the extension of class functionalities.

Add the __init__() Function

The __init__() function initializes the attributes of the class. It is automatically called when an object is
created.

14 | P a g e
Super() Function & Add Properties

The super() function allows you to call methods of the parent class within a child class, making it
easier to work with inheritance.

In Python, the `super()` function is used to call methods from a parent (or superclass) in a child (or
subclass). It's commonly used to extend the functionality of the parent class methods or to ensure that the
parent class initialization code runs when creating an instance of a subclass.

Here's how you can use the `super()` function and add properties in Python:

### Basic Usage of `super()`

1. Defining Parent and Child Classes:

class Parent:

def __init__(self, name):

self.name = name

def greet(self):

print(f"Hello, {self.name}!")

class Child(Parent):

def __init__(self, name, age):

super().__init__(name) # Call the __init__ method of Parent

self.age = age

def greet(self):

super().greet() # Call the greet method of Parent

print(f"I am {self.age} years old.")

In this example:

- `super().__init__(name)` calls the `__init__` method of the `Parent` class to initialize the `name` property.

- `super().greet()` calls the `greet` method of the `Parent` class to print the greeting before adding more
functionality in the `Child` class's `greet` method.

2. Using `super()` with Multiple Inheritance:

class Base1:

def __init__(self, value1):

self.value1 = value1

class Base2:

def __init__(self, value2):

self.value2 = value2

15 | P a g e
class Child(Base1, Base2):

def __init__(self, value1, value2, extra_value):

super().__init__(value1) # This will call __init__ from Base1

Base2.__init__(self, value2) # Explicitly call __init__ from Base2

self.extra_value = extra_value

In this example, `super()` handles the `Base1` initialization, while `Base2.__init__` is called explicitly.

Adding Properties

To add properties in a class, you can simply define them in the `__init__` method or as class
attributes. Here’s how you can add properties and use `super()`:

Sample Code:

class Animal:

def __init__(self, name, species):

self.name = name

self.species = species

def describe(self):

print(f"{self.name} is a {self.species}.")

class Dog(Animal):

def __init__(self, name, breed):

super().__init__(name, "Dog") # Call parent __init__

self.breed = breed

def describe(self):

super().describe() # Call parent describe method

print(f"{self.name} is a {self.breed} breed.")

# Example usage

dog = Dog("Rex", "Golden Retriever")

dog.describe()

Output:

Rex is a Dog.

Rex is a Golden Retriever breed.

In this example:

16 | P a g e
- The `Dog` class uses `super()` to call the `Animal` class's `__init__` method, passing the `"Dog"` string for
the species.

- It also overrides the `describe` method to add more detail about the breed.

17 | P a g e

You might also like