Python Programming
Dr. K Nagaraju,
Asst Prof, CSED,
IIITDM Kurnool
Inheritance defined
Inheritance is a powerful feature in object oriented
programming.
It refers to defining a new class with little or no
modification to an existing class. The new class is
called derived (or child) class and the one from
which it inherits is called the base (or parent) class.
Python Inheritance Syntax
class BaseClass:
Body of base class
class DerivedClass(BaseClass):
Body of derived class
Derived class inherits features from the base class, adding new features to it. This results
into re-usability of code.
Characteristics of Inheritance
Inheritance makes objects (classes) special
Derive new classes from existing ones
Extend the definition of existing classes
Override method definitions of existing classes
Create objects of different classes in the same
program
Allow objects to communicate with each other
Create more complex objects by combining simpler
ones
Guide to Programming3
with Python
Inheritance Models “is a” Relationship
Car
Van Sports car Convertible
Animals
Reptile Mammals Fish
Dog Cat Human
Using Inheritance to Create New
Classes
Inheritance: An element of OOP that allows a new
class to be based on an existing one where the
new automatically gets (or inherits) all of the
methods and attributes of the existing class
The children classes get all the capabilities
(methods) and properties (attributes) the parent
class has; the children classes are also called
derived classes
Get the code for free! (code-reuse) – inheritance
allows a new class to re-use code which already
existed in another class (the parent class)
Types of Inheritance
Single Inheritance in Python
When a child class inherits from only one parent
class, it is called single inheritance.
Python Inheritance Syntax
class BaseClass:
Body of base class
class DerivedClass(BaseClass):
Body of derived class
Example
class Parent:
def func1(self):
print("this is function one")
class Child(Parent):
def func2(self):
print(" this is function 2 ")
ob = Child()
ob.func1()
ob.func2()
this is function one
this is function 2
Defining a Base Class
# base class
class Vehicle():
def description(self):
print("I'm a Vehicle!")
Subclassing
# base class
class Vehicle():
def description(self):
print("I'm a Vehicle!")
# subclass
class Car(Vehicle):
pass
# create an object from each class
v = Vehicle()
c = Car()
[Link]()
# Prints I'm a Vehicle!
[Link]()
# Prints I'm a Vehicle!
Override a Method
# base class
class Vehicle():
def description(self):
print("I'm a Vehicle!")
# subclass
class Car(Vehicle):
def description(self):
print("I'm a Car!")
class Moped(Vehicle)
– Def description():
– print(“I am not a car, not a ship, I am a moped)
# create an object from each class
v = Vehicle()
c = Car()
[Link]()
# Prints I'm a Vehicle!
[Link]()
# Prints I'm a Car!
Shapes
Multiple Inheritance
When a child class inherits from more than one
parent class.
Syntax:
Class ParentClass1:
Body of the class
Class ParentClass2:
Body of the class
Class Child(ParentClass1, ParentClass2):
Body of the class
Multiple Inheritance
When a child class inherits from more than one parent class.
class Parent:
def func1(self):
print("this is function 1")
class Parent2:
def func2(self):
print("this is function 2")
class Child(Parent , Parent2):
def func3(self): Syntax:
Class ParentClass1:
print("this is function 3") Body of the class
Class ParentClass2:
Body of the class
Class Child(ParentClass1, ParentClass2):
ob = Child() Body of the class
ob.func1()
ob.func2()
ob.func3()
Multilevel Inheritance
When one class inherits from another, which in
turn inherits from another, it is multilevel python
inheritance.
Multilevel Inheritance
class Parent:
def func1(self):
print("this is function 1")
class Child(Parent):
def func2(self):
print("this is function 2")
class Child2(Child):
def func3(self):
print("this is function 2")
ob = Child2()
ob.func1()
ob.func2()
ob.func3()
Python Multiple Inheritance vs. Multi-
level Inheritance
Python Multiple Inheritance vs. Multi-
level Inheritance
Hybrid Inheritance
Hybrid inheritance involves multiple inheritance
taking place in a single program.
Hybrid Inheritance
class Parent:
def func4(self):
print("this is function one")
class Child(Parent):
def func2(self):
print("this is function 2")
class Child1(Parent):
def func3(self):
print(" this is function 3"):
class Child3(Child , Child1):
def func4(self):
print(" this is function 4")
ob = Child3()
ob.func4()
Till now
• You have seen
• The concept of inheritance in Python
• Types inheritance in Python
Now, will see
• How the super() function works
• How the super() function in single inheritance
works
• How the super() function in multiple inheritance
works
super()
• super() alone returns a temporary object of the superclass
that then allows you to call that superclass’s methods.
• super() builtin returns a proxy object (temporary object of
the superclass) that allows us to access methods of the
base class.
• Why would you want to do any of this?
– While the possibilities are limited by your imagination
– a common use case is building classes that extend the
functionality of previously built classes.
• Calling the previously built methods with super() saves
you from needing to rewrite those methods in your
subclass, and allows you to swap out superclasses with
minimal code changes.
Use of super()
• In Python, super() has two major use cases:
– Allows us to avoid using the base class
name explicitly
– Working with Multiple Inheritance
Lets see one example
class Rectangle:
def __init__(self, length, width):
[Link] = length
[Link] = width
def area(self):
return [Link] * [Link]
def perimeter(self):
return 2 * [Link] + 2 * [Link]
class Square:
def __init__(self, length):
[Link] = length >>> square = Square(4)
>>> [Link]()
16
def area(self): >>> rectangle = Rectangle(2,4)
>>> [Link]()
return [Link] * [Link] 8
def perimeter(self):
return 4 * [Link]
Single Inheritance
Is there any way to reduce the code?
Single Inheritance
Is there any way to reduce the code?
you can reduce the amount of code you write while
simultaneously reflecting the real-world relationship
between rectangles and squares:
Then how?
super() in Single Inheritance
class Rectangle:
def __init__(self, length, width):
[Link] = length
[Link] = width
def area(self):
return [Link] * [Link]
def perimeter(self):
return 2 * [Link] + 2 * [Link]
# Here we declare that the Square class inherits from the Rectangle class
class Square(Rectangle):
def __init__(self, length):
>>> square = Square(4)
super().__init__(length, length) >>> [Link]()
16
In this example, Rectangle is the superclass, and Square is the subclass.
• The super() builtin returns a proxy object, a
substitute object that can call methods of the base
class via delegation.
• This is called indirection (ability to reference base
object with super())
Still you can extend
class Square(Rectangle):
def __init__(self, length):
super().__init__(length, length)
class Cube(Square):
def surface_area(self):
face_area = super().area()
return face_area * 6
def volume(self): >>> cube = Cube(3)
>>> cube.surface_area()
face_area = super().area() 54
>>> [Link]()
27
return face_area * [Link]
super() in Multiple Inheritance
Multiple Inheritance Overview
super() in Multiple Inheritance
class Triangle:
def __init__(self, base, height):
[Link] = base
[Link] = height
def area(self):
return 0.5 * [Link] * [Link]
class RightPyramid(Triangle, Square):
def __init__(self, base, slant_height):
[Link] = base
self.slant_height = slant_height
def area(self):
base_area = super().area()
perimeter = super().perimeter()
return 0.5 * perimeter * self.slant_height + base_area
Did you guess that Python will try to
call [Link]()?
>> pyramid = RightPyramid(2, 4)
>> [Link]()
Traceback (most recent call last):
File "[Link]", line 63, in <module>
print([Link]())
File "[Link]", line 47, in area
base_area = super().area()
File "[Link]", line 38, in area
return 0.5 * [Link] * [Link]
AttributeError: 'RightPyramid' object has no attribute 'height'
This is because of something called the method resolution order.
Method Resolution Order (MRO)
• The method resolution order (or MRO) tells Python
how to search for inherited methods.
• This comes in handy when you’re using super()
because the MRO tells you exactly where Python
will look for a method you’re calling with super()
and in what order.
• Every class has an .__mro__ attribute that allows
us to inspect the order
Access Modifiers in Python
• Various object-oriented languages like C++, Java,
Python control access modifications which are
used to restrict access to the variables and
methods of the class.
• A Class in Python has three types of access
modifiers:
– Public Access Modifier
– Protected Access Modifier
– Private Access Modifier
Access Modifiers in Python
Python uses ‘_’ symbol to determine the access
control for a specific data member or a member
function of a class.
Access specifiers in Python have an important role to
play in securing data from unauthorized access
and in preventing it from being exploited.
Public Access Modifier
•The members of a class that are declared public are
easily accessible from any part of the program.
•All data members and member functions of a class
are public by default.
Public Access Modifier
# program to illustrate public access modifier in a class
class Student:
# constructor
def __init__(self, name, age):
# public data members
[Link] = name
[Link] = age
# public member function
def displayAge(self):
# accessing public data member
print("Age: ", [Link])
# creating object of the class
obj = Student("R2J", 20)
# accessing public data member
print("Name: ", [Link])
# calling public member function of the class
[Link]()
Private Access Modifier
• The members of a class that are declared private
are accessible within the class only, private access
modifier is the most secure access modifier.
• Data members of a class are declared private by
adding a double underscore ‘__’ symbol before the
data member of that class.
private access modifier
# program to illustrate private access modifier in a class
class Student:
# private members
__name = None
__roll = None
__branch = None
# constructor
def __init__(self, name, roll, branch):
self.__name = name
self.__roll = roll
self.__branch = branch
# private member function
def __displayDetails(self):
# accessing private data members
print("Name: ", self.__name)
print("Roll: ", self.__roll)
print("Branch: ", self.__branch)
# public member function
def accessPrivateFunction(self):
# accesing private member function
self.__displayDetails()
# creating object
obj = Student("R2J", 1706256, "Information Technology")
# calling public member function of the class
[Link]()
protected access modifier
# program to illustrate protected access modifier in a class
# super class
class Student:
# protected data members
_name = None
_roll = None
_branch = None
# constructor
def __init__(self, name, roll, branch):
self._name = name
self._roll = roll
self._branch = branch
# protected member function
def _displayRollAndBranch(self):
# accessing protected data members
print("Roll: ", self._roll)
print("Branch: ", self._branch)
# derived class
class CSEStu(Student):
# constructor
def __init__(self, name, roll, branch):
Student.__init__(self, name, roll, branch)
# public member function
def displayDetails(self):
# accessing protected data members of super class
print("Name: ", self._name)
# accessing protected member functions of super class
self._displayRollAndBranch()
# creating objects of the derived class
obj = CSEStu("R2J", 1706256, "Computer Science and Engineering")
# calling public member functions of the class
[Link]()
Python Inheritance Super Function – Super()
With inheritance, the super() function in
python actually comes in quite handy. It allows us
to call a method from the parent class. Let’s define
a new class for this.
43
Python override method
A subclass may change the functionality of
a Python method in the superclass. It does
so by redefining it. This is termed python
method overriding. Lets see this Python
Method Overriding Example.
44
Derived Classes are New Classes
To create specializations of existing classes or
objects by adding new attributes and methods!
– often called subtyping when applied to classes. In
specialization, the new class or object has data or
behavior aspects that are not part of the inherited
class.
Over-ridding (e.g., over-ridding of the + operator,
so + has different meaning, addition of two
numbers, concatenation of two strings, etc) – the
same method that does something different
Altering the Behavior of Inherited
Methods: Overriding
Override: To redefine how inherited method of
base class works in derived class
Two choices when overriding
– Completely new functionality vs. overridden method
– Incorporate functionality of overridden method, add
more
Understanding Polymorphism
Polymorphism: Aspect of object-oriented
programming that allows you to send same
message to objects of different classes, related by
inheritance, and achieve different but appropriate
results for each object
Working with Multiple Objects
We can have multiple objects in a program
Message: Communication between objects; one
object sends another a message when it invokes a
method of the other
(We already know that we can exchange
information among functions through parameters
and return values)