Table of Contents[Hide][Show]
In this lecture, we will learn about classes, constructors and inheritance in python.
These concepts are really important in a large program where different types are needed to be defined.
Classes
Classes are essential in programming and they’re not specific to python. Many other programming languages support the notion of classes. We use classes to define new data types.
So far, we have learned about the basic data types in Python like numbers, strings, and booleans. These are the basic or simple data types in Python. We have also seen a couple of complex data types like lists and dictionaries.
While these types are extremely useful, they cannot always be used to model complex concepts. For example, think about the idea of a point, or a shopping cart. A shopping cart is not a boolean or a list. It’s a different kind of data. So we can use classes to define new types to model real concepts.
Now, let’s define a new data type called point. This new type is going to have methods as we checked before.
This is how you will do it:
We start by defining a class by using the “class” keyword and right after that we give our class a name.
class Point
Now, look at the naming convention I’ve used here. I’ve capitalized the first letter here, this is what we call a pascal naming convention. This convention is different from the one we use for naming our variables and functions for which we always use lowercase letters and separate multiple words using an underscore. But when naming classes, we don’t use an underscore to separate multiple words instead, we capitalize the first letter of every word.
After defining our class, a colon is used which means that now a block is defined.
class Point:
def move (self):
In this block, we can define all the functions or methods that belong to points. For example, we can define a function called “move” for moving a point. Note that as soon as we type open parenthesis, PyCharm automatically adds “self” here. This is a special keyword and let me get back to this shortly. Let’s print “move” on the terminal.
print("move")
Let’s define another method like “draw” and print it on the terminal.
def draw(self):
print("draw")
We’re done with the definition of our “point” class. With this new type, we can create new objects. A class simply defines the blueprint or the template for creating objects which are the actual instances based on that blueprint. To create an object, we type out the name of our class and then call it just like a function. This creates a new object and then returns it. Then we can store that object in a variable. Let me show you:
Here we have defined a “point1” which is a three-dimensional point. You can see that, we can print individual coordinates on the terminal.
We can use the two methods “draw” and “move” with this point.
So to recap, we use classes to define new types and these types can have methods that we define in the body of the class. Classes can have attributes that we can set anywhere in our programs.
Constructors
So far, we have learned how to create new types using classes. Now there is a small problem with this implementation. We can create a point object without an x or y coordinate using classes and that is not ideal. Let me show you.
Let’s create a point and print it before we set the x coordinate. Running our program results in an attribute error like this:
It means that the point object has no attribute called x. Now the problem is that it is possible to have a point object without x or y coordinates. This doesn’t make sense as whenever we talk about a point, we need to know where that point is located. To solve this problem, we use a constructor. A constructor is a function that gets called at the time of creating an object.
Here is how we use a constructor. First, let’s pass the x and y coordinates values in the above program.
point = Point(10, 20)
print(point.x)
Now, we need to add a special method in this class called a constructor. Its syntax is like this:
def __init__(self, x, y):
init
is short for initialized, and this is the function or the method that gets called when a new point object is created. The x and y are added right after self
to add two extra parameters.
After that, we should map the x and y to the passed values i.e. 10 and 20
self.x = x
self.y = y
We use the self
to refer to the current object and then we set the x attribute to the x argument passed to the function “x”. In this way, using init
method, we can initialize our objects. This method is referred to as a constructor. Let’s run our program.
Now, we can change the x and y coordinates later. Let’s update x coordinate:
point = Point(10, 20)
point.x = 11
print(point.x)
Now, the x coordinate is updated to value 11.
Exercise
Here’s an interesting exercise for you.
I want you to define a new type called a person. These “Person” objects should have a “name
” attribute as well as a “talk()
” method.
It’s a simple task and should not take more than a couple of minutes.
Solution
Start with defining the class “Person” like this:
class Person:
self.name = name
We will define the constructor later. Now, we can create the “Person” object. Let’s call it John
john = Person("John Smith")
print(john.name)
john.talk()
Now, go on to the first portion of the code and create a constructor.
def __init__(self, name):
The final code will look like this:
You can also use formatted strings and other concepts in conjunction with classes and constructors.
Inheritance
Inheritance is another concept associated with classes that let you reuse a code.
Consider this piece of code.
class Dog:
def walk(self):
print("walk")
We have created a class “Dog” with a “walk” method. In this method, we’re simply printing the walk message on the terminal. Let’s say, in a real program, Ther are 10 lines of code instead of just one line here. In the future, if another class is needed to have the “walk” method, we will have to repeat all that code. This is not ideal.
In programming, we have a principle called DRY which is short for don’t repeat yourself. Let’s say sometime in the future, we discover a problem with our “walk” method and if we have repeated or duplicated this method in many other places, we’ll have to come back and fix that problem in every single place we have duplicated this code. So that’s why in programming we should not define something twice.
There are different approaches to remedy this problem but here we are going to learn the one which is easier for beginners and it is called inheritance. In this case, we will create another class “mammal” and define our “walk” attribute in that class.
class Mammal:
def walk(self):
print("walk")
After defining our “Mammal” class we can use inheritance to pass the attributes like this:
Both the dog and cat classes are inheriting all the class methods defined in their parent class. Now, we can add methods specific to dogs like this:
class Dog:
def bark(self):
print("bark")
Wrap Up!
This was all about the classes, constructors and reusing the code in classes with inheritance concepts. Now we are nearing the end of our series. By this point, you should be able to produce good, readable and concise codes in Python.
We will see the concept of modules and packages in the next lecture.
Leave a Reply