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

Class and Objects

Abstraction refers to hiding unnecessary details and focusing on important features. It partitions a program into independent concepts. Encapsulation means hiding implementation details under layers of abstraction. Abstraction solves problems at the design stage by focusing on what an object does rather than how, while encapsulation solves problems at the implementation stage by hiding code and data. Abstraction can be implemented using interfaces and abstract classes, while encapsulation uses access modifiers like public and private. The tutorial discusses these concepts and provides examples to explain abstraction and encapsulation in object-oriented programming.
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
56 views

Class and Objects

Abstraction refers to hiding unnecessary details and focusing on important features. It partitions a program into independent concepts. Encapsulation means hiding implementation details under layers of abstraction. Abstraction solves problems at the design stage by focusing on what an object does rather than how, while encapsulation solves problems at the implementation stage by hiding code and data. Abstraction can be implemented using interfaces and abstract classes, while encapsulation uses access modifiers like public and private. The tutorial discusses these concepts and provides examples to explain abstraction and encapsulation in object-oriented programming.
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 17

Abstraction & Encapsulation | Python Tutorials For Absolute Beginners In

Hindi #59

Our today's tutorial is based mainly on theory because coding is not just
about learning new concepts but also about understanding them. Let us
give our PyCharm some rest and try to learn some theory about
Abstraction and Encapsulation, which are fundamental concepts for our
tutorials ahead.

What is Abstraction?
Abstraction refers to hiding unnecessary details to focus on the whole
product instead of parts of the project separately. It is a mechanism that
represents the important features without including implementation
details. Abstraction helps us in partitioning the program into many
independent concepts so we may hide the irrelevant information in the
code. It offers the greatest flexibility when using abstract data-type
objects in different situations.

Example of Abstraction:
Let us take the example of a car. It has an engine, tires, windows,
steering wheel, etc. All these things combine to form a car, which is an
abstraction, and all the different parts are its layers of abstraction. Now
an engine is composed of various parts such as camshaft, valves, oil
pan, etc. these flayers the engine is an abstraction. In simple words,
abstraction can be achieved by hiding the background details and
showing only the necessary ones. In programming, abstraction can not
be achieved without Encapsulation.

What is Encapsulation?
Encapsulation means hiding under layers. When working with classes
and handling sensitive data, global access to all the variables used in
the program is not secure. In Encapsulation, the internal representation
of an object is generally hidden from the outside to secure the data. It
improves the maintainability of an application and helps the developers
to organize the code better.

Example of Encapsulation
We can take an example of a capsule in which the medicine is
encapsulated. We have often used examples of bigger projects in which
many programmers contribute according to their tasks. In the end, the
whole project is done by joining the contribution of each participant. Well,
this is what Encapsulation aims to achieve.

Abstraction and Encapsulation are fundamental concepts of OOP.


Encapsulation takes all the worry away from the user, providing him with
just the product that he requires, irrespective of the way it is formed.
Abstraction focuses on the working of the object instead of the how part,
while Encapsulation is all about hiding the way or method of working and
just providing the working model.

Classes can be a perfect example of abstraction as each team member


is given a separate class to work on, to develop a more significant
project. A person working in a class only knows his job. While
Encapsulation can be said to hide the code from normal users by making
a front end through which the user can interact through the software
without direct access to the code.

Abstraction Encapsulation
Encapsulation is used to solve the
Abstraction is used to solve the problem
problem and issue that arise at the
and issues that arise at the design stage.
implementation stage.
Abstraction focuses on what the object Encapsulation focuses on hiding the code
does instead of how the details are and data into a single unit to secure the
implemented. data from the outside world.
Encapsulation can be implemented using
 Abstraction can be implemented by
Access Modifiers (Public, Protected, and
using Interface and Abstract Class.
Private.)
  Its application is during the design Its application is during the
level. Implementation level.
 This tutorial is all about understanding the concept of Abstraction and
Encapsulation. Check the next tutorials to learn how to implement more
OOP concepts in Python.

In today’s tutorial, we are going to learn about Single inheritance in


Python. Before discussing the concept of inheritance in Python, we
should have some knowledge about the word itself. Inheritance means
to receive something from one’s parents or ancestors. The concept of
inheritance is very similar in cases of classes where a class inherits all
the properties and methods of its previous class that it is inheriting from.
“Inheritance is the ability to define a new class(child class) that is a
modified version of an existing class(parent class)”

Syntax:
class Parent_class_Name:
#Parent_class code block
class Child_class_Name(Parent_class_name):
#Child_class code block
Copy
The above syntax consists of two classes declared. One is the parent
class or by other means, the base class, and the other one is the child
class which acts as the derived class.

Two common terms related to inheritance are as follows:

 Parent: The parent class is the one that is giving access to its
methods or properties to the child class or derived class.
 Child: Child class is the one that is inheriting methods and
properties from the parent class.

The class that is inheriting, i.e., the child class, can inherit all the
functionality of the parent class and add its functionalities also. As we
have already discussed that each class can have its constructors and
methods, so in case of inheritance the child class can make and use its
constructor and also can use the constructor of the parent class. We can
simply construct it as we did for the parent class but OOP has provided
us with a simple and more useful solution known as Super().

We will be discussing super() and overriding in our Super() and


Overriding In Classes tutorial of the course.

Single inheritance exists when a class is only derived from a single base
class. Or in other words when a child class is using the methods and
properties of only a single parent class then single inheritance exists.
Single inheritance and Multiple inheritance are very similar concepts, the
only major difference is the number of classes. We will see Multiple
Inheritance  in our next tutorial.

Different forms of Inheritance:


1. Single inheritance: When a child class inherits from only one
parent class then it is called single inheritance.
2. Multiple inheritance: When a child class inherits from multiple
parent classes then it is called multiple inheritance

Below is an example of single inheritance in Python.


class Parent():
def first(self):
print('Parent function')

class Child(Parent):
def second(self):
print('Child function')

object1 = Child()
object1.first()
object1.second()
Copy
Output: 
Parent function
Child function
Copy

Advantages of Inheritance:

 It increases the code’s reusability as we do not have to copy the


same code again to our new class.
 It makes the program more efficient.
 We can add more features to our already built class without
modifying it or changing its functionality.
 It provides a representation of real-world relationships.

In this tutorial, we have discussed the Inheritance concept. Inheritance is


among the most significant concepts in object-oriented programming
technique which provides code reusability, readability and helps in
building optimized and efficient code.
Code as described/written in the video

class Employee:
no_of_leaves = 8

def __init__(self, aname, asalary, arole):


self.name = aname
self.salary = asalary
self.role = arole

def printdetails(self):
return f"The Name is {self.name}. Salary is {self.salary}
and role is {self.role}"

@classmethod
def change_leaves(cls, newleaves):
cls.no_of_leaves = newleaves

@classmethod
def from_dash(cls, string):
return cls(*string.split("-"))

@staticmethod
def printgood(string):
print("This is good " + string)

In multiple inheritance, a class is derived from more than one class


i.e. multiple base classes. The child class, in this case, has features
of both the parent classes."

As the name implies, python's multiple inheritance is when a class


inherits from more than one class. This concept is very similar to
multilevel inheritance, which also is our next topic of this course. It is
also nearly the same as a single-level inheritance because it contains all
of the same functionality, except for the number of base classes. 

While using the concept of multiple inheritance, the order of placing the
base classes is very important. Let us clear the concept using an
example. Suppose we have a child class named Child, and it has two
base classes, named Base1 and Base2.

Example:
class Base1:
def func1(self):
print("this is Base1 class")
class Base2:
def func2(self):
print("this is Base2 class")

class Child(Base1 , Base2):


def func3(self):
print("this is Base3 class")

obj = Child()
obj.func1()
obj.func2()
obj.func3()
Copy
Output:

this is Base1 class

this is Base2 class

this is Base3 class

Now, when we are looking for some attribute, let it be a constructor.


Then the program will search the current class i.e., the Child1 class first.
If it does not find it in the Child1, it will look in the base class that is
present at the leftmost side, which is Base1. After that, the program will
start moving from left to right in a sequential manner, hence searching
the Base2 class at the end. We should always give attention to the
ordering of the base classes because it helps us a lot when multiple
classes contain the same methods and also in method overriding. 

Method Overriding:
Override means having two methods that have the same name. They
may perform same tasks or different tasks. In python, when the same
method defined in the parent class is also defined in the child class, the
process is known as Method overriding. This is also true when multiple
classes have the same method and are linked together somehow.  

There are few rules for Method overriding that should be followed:

 The name of the child method should be the same as parents.


 Inheritance should be there, and we need to derive a child class
from a parent class
 Both of their parameters should be the same. 

In this case, the child method will run, and the reason for which, we have
discussed in the paragraph above, related to ordering. Multiple
inheritance is based on the same concept on which the single
inheritance is based on i.e., DRY (do not repeat yourself). Multiple
inheritance makes it easier to inherit methods and attributes from base
classes that implement the functionality. When done right, we can reuse
the code without having to copy-and-paste a similar code to implement
interfaces.   

Code as described/written in the video

class Employee:
no_of_leaves = 8
var = 8

def __init__(self, aname, asalary, arole):


self.name = aname
self.salary = asalary
self.role = arole

def printdetails(self):
return f"The Name is {self.name}. Salary is {self.salary}
and role is {self.role}"

@classmethod
def change_leaves(cls, newleaves):
cls.no_of_leaves = newleaves

@classmethod
def from_dash(cls, string):
return cls(*string.split("-"))

@staticmethod
def printgood(string):
print("This is good " + string)

What is Multilevel Inheritance in Python?


In multilevel inheritance, a class that is already derived from another
class is derived by a third class. So in this way, the third class has all the
other two former classes' features and functionalities. The syntax looks
something like this:
class Parent1:
pass
class Derived1(Parent1):
pass
class Derived2(Derived1):
pass
Copy
Now let us dive into the priority brought by the ordering of the class.
Suppose that we are looking for a constructor or a value for any variable.
Our program will first check our current class i.e., Derived2, for it. If
nothing is found, then it will move towards Derived1 and in order at last
towards Parent1 until it finds the constructor or variable in the way.

If we have the same method or variable in the base and derived class,
then the order we discussed above will be followed, and the method will
be overridden. Else, if the child class does not contain the same method,
then the derived1 class method will be followed by the sequence defined
in the paragraph above.

For Example:
class level1:
def first(self):
print ('code')

class level2(level1): #inherit level1


def second(self):
print ('with')

class level3(level2): #inherit level2


def third(self):
print ('harry')

obj=level3()
obj.first()
obj.second()
obj.third()
Copy

Rules for Method overriding:-


There are few rules for Method overriding that should be followed:

 The name of the child method should be the same as parents.


 Inheritance should be there, and we need to derive a child class
from a parent class
 Both of their parameters should be the same.

Multiple inheritance VS. Multilevel inheritance


Multiple inheritance Multilevel inheritance
 Multiple Inheritance is where a class  In multilevel inheritance, we inherit
inherits from more than one base from a derived class, making that
class. derived class a base class for a new
 Sometimes, multiple Inheritance class.
makes the system more complex,  Multilevel Inheritance is widely used. It
that’s why it is not widely used. is easier to handle code when using
multilevel inheritance.
 Multiple Inheritance has two class
 Multilevel Inheritance has three class
levels; these are base class and
levels, which are base class, intermediate
derived class.
class, and derived class.

Advantages of Inheritance

1. It reduces code redundancy.


2. Multilevel inheritance provides code reusability.
3. Using multilevel inheritance, code is easy to manage, and it
supports code extensibility by overriding the base class
functionality within child classes

Code as described/written in the video

class Dad:
basketball =6

class Son(Dad):
dance =1
basketball = 9
def isdance(self):
return f"Yes I dance {self.dance} no of times"

class Grandson(Son):
dance =6
guitar = 1

def isdance(self):
return f"Jackson yeah!" \
f"Yes I dance very awesomely {self.dance} no of times"

darry = Dad()
larry = Son()
harry = Grandson()

# print(darry.guitar)
# electronic device

Public, Private & Protected Access Specifiers | Python Tutorials For Absolute
Beginners In Hindi #63

In high-level programming languages like C++, Java, etc., private,


protected, and public keywords are used to control the access of class
members or variables. However, Python has no such keywords. Python
uses a convention of prefixing the name of the variable or method with a
single underscore(_) or double underscore(__) to emulate the behavior
of protected and private access specifiers.

Access modifiers are used for the restrictions of access any other class
has on the particular class and its variables and methods. In other
words, access modifiers decide whether other classes can use the
variables or functions of a specific class or not. The arrangement of
private and protected access variables or methods ensures the principle
of data encapsulation. In Python, there are three types of access
modifiers.

 Public Access Modifier


 Protected Access Modifier
 Private Access Modifier

Public Access Modifier:


In public, all the functions, variables, methods can be used publicly.
Meaning, every other class can access them easily without any
restriction. Public members are generally methods declared in a class
that is accessible from outside the class. Any ordinary class is, by
default, a public class. So, all the classes we had made till now in the
previous tutorials were all public by default.

Example of public access modifier:


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

Protected Access Modifier:


In the case of a protected class, its members and functions can only be
accessed by the classes derived from it, i.e., its child class or classes.
No other environment is permitted to access it. To declare the data
members as protected, we use a single underscore “_” sign before the
data members of the class.

Example of protected access modifier:


class employee:
def __init__(self, name, age):
self._name=name # protected attribute
self._age=age # protected attribute
Copy

Private Access Modifier:


In the case of private access modifiers, the variables and functions can
only be accessed within the class. The private restriction level is the
highest for any class. To declare the data members as private, we use a
double underscore “__” sign before the data members of the class. Here
is a suggestion not to try to access private variables from outside the
class because it will result in an AttributeError. 

Example of private access modifier:


class employee:
def __init__(self, name, age):
self.__name=name # private attribute
self.__age=age # private attribute
Copy

Name mangling in Python:


Python does not have any strict rules when it comes to public, protected,
or private, like java. So, to protect us from using the private attribute in
any other class, Python does name mangling, which means that every
member with a double underscore will be changed to
_object._class__variable when trying to call using an object. The
purpose of this is to warn a user so he does not use any private class
variable or function by mistake without realizing its states.

The use of single underscore and double underscore is just a way of


name mangling because Python does not take the public, private and
protected terms much seriously so we have to use our naming
conventions by putting single or double underscore to let the fellow
programmers know which class they can access or which they can’t.

Code as described/written in the video

# Public -
# Protected -
# Private -

class Employee:
no_of_leaves = 8
var = 8
_protec = 9
__pr = 98

def __init__(self, aname, asalary, arole):


self.name = aname
self.salary = asalary
self.role = arole

def printdetails(self):
return f"The Name is {self.name}. Salary is {self.salary}
and role is {self.role}"

@classmethod
def change_leaves(cls, newleaves):
cls.no_of_leaves = newleaves

@classmethod
def from_dash(cls, string):
return cls(*string.split("-"))
@staticmethod
def printgood(string):
print("This is good " + string)

emp = Employee("harry", 343, "Programmer")


print(emp._Employee__pr)

What Is Polymorphism?
In the basic English language, Polymorphism means to exist in different
states. The same object or thing changing its state from one form to
another is known as polymorphic. The same function or method, being
used differently in different scenarios, can perfectly describe
Polymorphism. It occurs mostly with base and derived classes.  

Understanding Polymorphism in Python:


The concept of Polymorphism has very strong ties with the method
overriding concept that we will learn in the next tutorial,
i.e., tutorial#65 of this course, along with the super() function. In
Python, it is mostly related to objects or the values of variables that are
assigned in different classes. For example, suppose a method in the
child class has the same name as the methods in the parent class, and
also they take the same number of variables as parameters. In that
case, the child class will inherit the methods from the parent class and
will override the method too. Meaning that the compiler will execute the
method in the child because it will be the first place it looks while
searching for the method when called. By overriding a method, we can
also add some more functionalities in it, so in a way modifying the
method in the child class but letting it remain the same in the parent
class.

For example:
len("Python") # returns 6 as result
len([1,2,3,4,5,6,7,8,9]) # returns 9 as result
Copy
Python also implements Polymorphism using methods. The len() method
returns the length of an object. In this case, the function len() is
polymorphic as it is taking a string as input in the first case, which
returns the total length/characters of the string, and in the second case,
it is taking list as input.

 Polymorphism is a very important concept. Although being a theoretical


concept, it is of great importance as it teaches us to use one entity, let it
be a method or variable, differently at different places. By applying the
concept of Polymorphism, we can save our time and make our code
more efficient and compact by using the DRY (Don't Repeat Yourself)
concept, which is the basis of Oop.

We can apply the concept of Polymorphism to the methods, objects,


functions, and inheritance. Even though the syntax and rules differ, but
the concept remains the same. 

Polymorphism in '+' operator:-


Take a look at the below example:
print(5+6)
print("5" + "6")
Copy
In the above example, we have used the '+' arithmetic python operator
two times in our programs. This is an example of the implementation of
Polymorphism in Python. We can use the same + operator to add two
integers, concatenate two strings, or extend two lists. The + arithmetic
operator acts differently depending on the type of objects it is operating
upon.

Code as described/written in the video


print(5+6)
print("5" + "6")

How to override class methods in Python?


Overriding occurs when a derived class or child class has the same
method that has already been defined in the base or parent class. When
called, the same methods with the same name and number of
parameters, the interpreter checks for the method first in a child class
and runs it ignoring the method in the parent class because it is already
overridden. In the case of instance variables, the case is a little different.
When the method is called, the program will look for any instance
variable having the same name as the one that is called in the child,
then in the parent, and after that, it comes again into child class if not
found.

Where does super() fit in all this?


When we want to call an already overridden method, then the use of the
super function comes in. It is a built-in function, so no requirement of any
module import statement. What super does is it allows us to use the
method of our superclass, which in the case of inheritance is the parent
class. Syntax of using super() is given below:
class Parent_Class(object):
def __init__(self):
pass

class Child_Class(Parent_Class):
def __init__(self):
super().__init__()
Copy
super() returns a temporary object of the superclass that then allows you
to call that superclass’s methods. The primary use case of super() is to
extend the functionality of the inherited method.

We have discussed earlier that in the case of method overriding, the


previous method could not be called, but super makes an exception, and
thus we can partially or completely use the method of the parent class
too. We can even use super() to call only a specific variable we used in
our overridden method. Calling the superclass-built methods with super()
saves us from rewriting those methods in our subclass and allows us to
swap out superclasses with minimal code changes.

Code as described/written in the video:


class A:
classvar1 = "I am a class variable in class A"
def __init__(self):
self.var1 = "I am inside class A's constructor"
self.classvar1 = "Instance var in class A"
self.special = "Special"

class B(A):
classvar1 = "I am in class B"

def __init__(self):
self.var1 = "I am inside class B's constructor"
self.classvar1 = "Instance var in class B"
# super().__init__()
# print(super().classvar1)

a = A()
b = B()

print(b.special, b.var1, b.classvar1)

You might also like