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

08_20241028_OOP

This document provides a comprehensive overview of Object-Oriented Programming (OOP) principles in Python, including encapsulation, abstraction, inheritance, and polymorphism. It explains key concepts such as classes, objects, attributes, methods, and the use of the 'self' variable, alongside practical examples. The document also discusses the advantages of OOP, including modularity, code reusability, and the benefits of using properties for controlled access to attributes.

Uploaded by

scs623170
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

08_20241028_OOP

This document provides a comprehensive overview of Object-Oriented Programming (OOP) principles in Python, including encapsulation, abstraction, inheritance, and polymorphism. It explains key concepts such as classes, objects, attributes, methods, and the use of the 'self' variable, alongside practical examples. The document also discusses the advantages of OOP, including modularity, code reusability, and the benefits of using properties for controlled access to attributes.

Uploaded by

scs623170
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 37

Object Oriented Programming (OOP)

Prof. Murali Krishna Gurram


Dept. of Geo-Engineering & RDT
Centre for Remote Sensing, AUCE
Andhra University, Visakhapatnam – 530 003
Dt. 28/10/2024
Basic Elements of Python

Object Oriented Programming


a. Object Oriented concepts and terminology
b. Custom classes, attributes and methods
c. Inheritance and Polymorphism
d. using properties to control attribute access
1. Introduction to Object-Oriented
Programming (OOP)
1. Introduction to Object-Oriented Programming (OOP)
Object-Oriented Programming (OOP) Principles in Python
Object-Oriented Programming (OOP) revolves around creating objects
that encapsulate both data (attributes) and behavior (methods) related
to a real-world entity. The primary principles include:

• Encapsulation: Bundling of data and methods within a class to limit


external interference and misuse.

• Abstraction: Simplifying complex reality by modeling classes


appropriate to the problem.

• Inheritance: Creating new classes based on existing classes to enhance


code reusability.

• Polymorphism: Allowing objects to be treated as instances of their


parent class.
Each principle is intended to improve code readability, reusability, and
maintainability. Let’s dive into each principle in detail.
1. Introduction to Object-Oriented Programming (OOP)
Object-Oriented Programming (OOP) Principles in Python
1. Introduction to Object-Oriented Programming (OOP)

Object-Oriented Programming (OOP) Principles in Python

• By understanding these core OOP concepts, you’re equipped to write


more organized, reusable, and efficient Python code.

• With these foundations, you can tackle complex problems by


modeling them as objects and using OOP principles to manage
interactions among them.
1. Introduction to Object-Oriented Programming (OOP)
Advantages of OOP:
• Modularity: Divides the program into parts, making it easier to
maintain.

• Code Reusability: Inheritance allows existing code to be reused.

• Encapsulation: Wraps attributes and methods together to


protect the data.

• Abstraction: Hides complex implementation, exposing only what


is necessary.

• Polymorphism: Methods can be used in different ways


depending on the object, adding flexibility.
2. Key OOP Terminology and Concepts
Classes and Objects:

• A class is a blueprint, defining the structure and behavior


(methods) of objects.

• An object is an instance of a class, with attributes (data) and


methods (functions).
– In Python, everything is treated as an object be it functions, modules,
data types etc.
2. Key OOP Terminology and Concepts
Classes and Objects:
Example: Class and Object Structure
class Dog:  The definition of class in
Python starts with the keyword
# Constructor to initialize attributes
class followed by the name of
def __init__(self, name, breed): the class and colon(:).
self.name = name
self.breed = breed  After the declaration of the
class is the body of the class
# Method to describe the dog which contains variables, data,
def bark(self): and functions.
print(f"{self.name} says Woof!")
 These related data, variables,
and functions are bound
# Creating an object of Dog
together in a class and this
my_dog = Dog("Buddy", "Golden Retriever") binding is called Encapsulation.
my_dog.bark() # Output: Buddy says Woof!

In this example, Dog is a class, while my_dog is an instance of that class.


2. Key OOP Terminology and Concepts
Classes and Objects:
Example: Let’s define a simple class of cars.
class car:
"A simple class for cars"

#Constructor to initialize
def __init__(self,company,color):
self.company = company
self.color = color
#function to print car company and color
def display(self):
print ('This is a', self.color, self.company)
2. Key OOP Terminology and Concepts
Classes and Objects:
Here we have defined a Python class.
First is class declaration followed by documentation string. The docstring can be
accessed using class_ name.__doc__ i.e. car.__doc__

After docstring is the __init__ method.

__init__ method
__init__ method is used for the initialization of the data members. This serves
as the constructor for the class and as any function, it can take any number of
arguments.

The __init__function is automatically invoked when the object of the class is


created.

After __init__ method is another function called display to print the car
company and color as supplied to the function.
2. Key OOP Terminology and Concepts
Classes and Objects:
What is that 'self' variable?
 In Python, self is a special variable used in instance methods to
represent the instance of the class on which a method is being
called.

 self is a reference to the current object, allowing access to the


instance's attributes and methods.

 By convention, self is the first parameter of any method in a


class, although you could technically name it anything (although
this is not recommended, as self is widely understood in Python
and makes code more readable).
2. Key OOP Terminology and Concepts
Classes and Objects:
Purpose of 'self'
 Accessing Attributes: self allows instance methods to access and modify the
attributes of the instance.
 Without self, the method would not know which instance’s data it’s working
with.

 Calling Other Methods: self lets methods call other methods within the
same instance.

 Unique to Each Instance: Each instance has its own self reference, so
attributes and methods can be used separately in each instance.
2. Key OOP Terminology and Concepts
Classes and Objects:
What is that 'self' variable?
 Well in every method inside a Python class, self is used as the reference to
the object of the class. It is included in a function as a first parameter.

 When the function defined inside a class is invoked, self refers to the object
of the class.

 We do not need to pass self as argument while calling the function.

 Python will automatically include it when the function is called.


2. Key OOP Terminology and Concepts
Classes and Objects:
How 'self' Works in a Class
class Dog: self.name = name and self.breed = breed
def __init__(self, name, breed): store name and breed as attributes unique to
self.name = name # self.name is an each Dog instance.
instance attribute
self.breed = breed # self.breed is In the bark method, self.name accesses the
another instance attribute name attribute of the specific instance (dog1
or dog2) that called bark.
def bark(self):
print(f"{self.name} says woof!")

# Creating two instances of the Dog class


dog1 = Dog("Buddy", "Golden Retriever")
dog2 = Dog("Bella", "Labrador")

dog1.bark() # Output: Buddy says woof!


dog2.bark() # Output: Bella says woof!
2. Key OOP Terminology and Concepts
Classes and Objects:
Why We Need self in Instance Methods
• When you define a method in a class, Python needs a way to
know which instance (object) it’s working with.

The self parameter:


• Points to the instance calling the method.

• Allows data sharing within an instance of the class, making sure


each instance’s data remains independent.
2. Key OOP Terminology and Concepts
Classes and Objects:
Common Questions About 'self'
• Why 'self' is not a keyword: Unlike keywords like class or def, self
is not a reserved keyword in Python.

• It’s simply a convention. You could technically name it something


else, but self is universally understood and keeps code readable.

• Why 'self' is needed explicitly: In some languages, like Java or


C++, the equivalent of self is implicit.

• In Python, it’s explicit to ensure clarity and avoid accidental errors


by distinguishing instance variables from local or global variables.
2. Key OOP Terminology and Concepts
Classes and Objects - Attributes and Methods:
• Attributes define the characteristics of an object (e.g., name, breed).
• Methods represent actions or behaviors of an object (e.g., bark()).

Example: Modifying Attributes Using Methods


class Person:
def __init__(self, name, age):
self.name = name
self.age = age

def birthday(self):
self.age += 1
print(f"Happy Birthday, {self.name}! You are now {self.age}.")

alice = Person("Alice", 30)


alice.birthday() # Output: Happy Birthday, Alice! You are now 31.
3. Custom Classes, Attributes and Methods
When creating custom classes, you define attributes and methods
that make sense for the type of object you’re modeling.
Python allows for various access levels, typically through public and
private attributes.

• Public Attributes: Accessible directly from outside the class.

• Private Attributes: Usually prefixed with an underscore


(_attribute_name), meant for internal use.
3. Custom Classes, Attributes and Methods

Example: Access Control with Public and Private Attributes

class Employee:
def __init__(self, name, salary):
self.name = name # Public attribute
self._salary = salary # Private attribute
def give_raise(self, amount):
self._salary += amount
print(f"{self.name}'s new salary: {self._salary}")
# Usage
emp = Employee("John Doe", 50000)
emp.give_raise(5000) # John's new salary: 55000
The private attribute _salary is only modified through the give_raise method, ensuring
data control.
3a. Python built-in class attributes
There are certain built-in class attributes in Python which can be accessed using
a dot(.) operator.
Python class attributes with description
__dict__
Returns a dictionary of classes namespace.
__doc__
Returns the class documentation string, if defined.
__module__
Return the name of the module in which the class is defined.
__name__
Return the name of the class.

The private attribute _salary is only modified through the give_raise method, ensuring
data control.
3a. Python built-in class attributes
Example: to demonstrate how these attributes can be used in the program.

class car:
"A simple class for cars"

#Constructor to initialize
def __init__(self,company,color):
self.company = company
self.color = color #making color private

#function to print car company and color


def display(self):
print ('This is a', self.color, self.company)

print ('car.__name__ = ',car.__name__)


print ('car.__doc__ = ',car.__doc__)
print ('car.__module__ = ',car.__module__)
print ('car.__dict__ = ',car.__dict__)
4. Inheritance and Method Overriding

Inheritance allows a new class (subclass) to inherit attributes and


methods from an existing class (superclass).

This is useful for creating a hierarchy of related classes without


repeating code.

• Superclass (Parent Class): A general class that contains common


attributes and methods.

• Subclass (Child Class): A specialized class that inherits from the


superclass and can add or override methods.

Method Overriding: Subclasses can redefine methods of the


superclass to tailor behavior.
4. Inheritance and Method Overriding
Example: Inheritance and Method Overriding
class Animal:
def speak(self):
print("Animal speaks.")

class Dog(Animal):
def speak(self):
print("Woof Woof!") # Overrides the speak method

class Cat(Animal):
def speak(self):
print("Meow!") # Overrides the speak method

# Demonstrating polymorphism
animals = [Dog(), Cat()]
for animal in animals:
animal.speak() # Outputs "Woof Woof!" and "Meow!" based on the class
4. Inheritance and Method Overriding
Benefits of Inheritance:

• Avoids code duplication by inheriting shared functionality.

• Enables polymorphic behavior, allowing subclasses to override


or extend superclass behavior.
5. Polymorphism
Polymorphism enables flexibility by allowing different classes to
use the same interface (methods).

This is often achieved through method overriding in subclasses.

• Polymorphic Functions: Functions that behave differently based


on the object they’re interacting with.

• Duck Typing: A principle in Python that emphasizes "If it walks


like a duck and quacks like a duck, it’s a duck."

• In other words, if an object supports a particular interface, it can


be used in a polymorphic manner.
5. Polymorphism
Example: Using Polymorphism with Method Overriding
class Shape:
def area(self):
raise NotImplementedError("Subclasses must implement this method")

class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height

def area(self):
return self.width * self.height

class Circle(Shape):
def __init__(self, radius):
self.radius = radius

def area(self):
import math
return math.pi * self.radius ** 2

shapes = [Rectangle(3, 4), Circle(5)]


for shape in shapes:
print("Area:", shape.area()) # Outputs area for each shape based on its type
6. Encapsulation and Using Properties
Encapsulation is a way to safeguard attributes by keeping
them private and using properties to control access.

• Getter (@property): Allows retrieval of a private


attribute in a controlled manner.

• Setter (@attribute_name.setter): Validates or


modifies values before assigning them to an attribute.
6. Encapsulation and Using Properties
built-in properties
• In Python, built-in properties are mechanisms that help
control how an attribute of an object is accessed or modified.

• The most commonly used built-in property in Python is the


@property decorator, which allows you to define getter and
setter methods to control attribute access.

• Built-in properties provide encapsulation by allowing


controlled access to attributes while keeping the
implementation details hidden.
6. Encapsulation and Using Properties
built-in properties
Example: Using @property for Controlled Access
class Person: @property is used to make the
def __init__(self, name, age): age attribute behave like a public
self._name = name # Private attribute attribute, while still allowing
self._age = age # Private attribute
control over how it’s set.
@property
def age(self): Trying to assign a negative age,
return self._age for instance, raises an error.
@age.setter
def age(self, value):
if value < 0:
raise ValueError("Age cannot be negative.")
self._age = value
@property
def name(self):
return self._name
# Usage
person = Person("Alice", 30)
print(person.age) # Accessing the age via the getter
person.age = 35 # Setting a new age using the setter
6. Encapsulation and Using Properties
Benefits of Using Properties
Using properties allows for flexibility and control over attribute access.
Here’s why properties are beneficial:

• Encapsulation: Control internal data access without exposing direct


access to private attributes.

• Validation: Perform checks before assigning values (like ensuring age is


non-negative).

• Read-Only Attributes: Define attributes that can be accessed but not


modified by omitting the setter method.
6. Encapsulation and Using Properties
Benefits of Using Properties
Example: Creating a Read-Only Property
class Circle: area is a read-only property
def __init__(self, radius): calculated based on the
self._radius = radius radius.
Since it doesn’t have a setter,
@property it can’t be modified directly.
def radius(self):
return self._radius

@property
def area(self):
import math
return math.pi * (self._radius ** 2)

# Usage
circle = Circle(5)
print(circle.radius) # Access radius
print(circle.area) # Access area, calculated as a property
6. Encapsulation and Using Properties
built-in properties
The @property Decorator
The @property decorator allows us to define a method that
behaves like an attribute.
It enables controlled access to private or protected attributes
and allows us to add custom logic when getting or setting an
attribute value.
• Getter: The method decorated with @property acts as a
getter for a private attribute.
• Setter: The method decorated with @attribute_name.setter
allows controlled assignment of values to the attribute.
• Deleter: The method decorated with
@attribute_name.deleter enables deleting the attribute (less
commonly used but available).
6. Encapsulation and Using Properties
Example: Using Properties to Control Attribute Access
class Product:
def __init__(self, name, price):
self.name = name
self._price = price # Private attribute

@property
def price(self):
return self._price

@price.setter
def price(self, value):
if value < 0:
raise ValueError("Price cannot be negative.")
self._price = value

# Example of using properties


product = Product("Laptop", 1000)
print(product.price) # Accesses price using the getter
product.price = 1200 # Uses the setter to change the price
6. Encapsulation and Using Properties
Advantages of Using Properties:
• Encapsulates logic for accessing and modifying
attributes.

• Prevents accidental modification of sensitive data.

• Provides a way to implement additional functionality


when setting attributes.
6. Encapsulation and Using Properties
Best Practices

• Start with clear classes and well-defined attributes and


methods.
• Use inheritance to avoid redundancy but avoid deep inheritance
hierarchies.
• Apply polymorphism judiciously to keep code adaptable to
future changes.
• Employ properties for sensitive data to ensure encapsulation
and controlled access.
• Write clean, self-explanatory code by naming methods and
attributes meaningfully.
Q&A

You might also like