Can you think of other classes that fit this example?
Objects Vs Classes
You cannot use classes like you do variable or function, you must create an instance of them
The operation is known as instantiation
It creates a new copy of the variables in the class
The new instance is known as an object
We use the functions and variables in the object NOT the class
# THIS IS WRONG!
Student.register_course(course) # Which student will python register?
Objects Vs Classes
Think of a class as a house blueprint (a plan)
It tells us how the house will look like
But we cannot live in it
We can create many houses from it
Each built house will have a different faimily living in it
The built houses are all instances of the house designed in the plan
Objects Vs Classes
Similarly, we are all Human
Human is the class
Myself, an each one of you, is an instance of class Human
We all have heads, hands, feet, and characteristics associated with humans
Yet each of us is unique in that we have our own names and personal characteristics
The individuals are the objects of class Human
Objects Vs Classes
Can you think of other examples?
Can you think of variables and functions associated with these classes?
Speaking of Functions and Variables
In OOP, we no longer call functions defined in classes as functions
They are now called methods
But they are identical in every way to functions
Except it can work on the variables in the object
Speaking of Functions and Variables
Variables defined in objects also get a name change to distinguish them from regular variables
We call them instance variables, properties, or attributes
Similarly, everything you know about variables apply to them
Only difference is scope
The whole idea of putting variables in classes is to make them in scope for class methods for easy access
Object Oriented Programming (OOP)
Where is the benefit here?
Mainly in code reusability
OOP allows for inheritance
Meaning, that we can derive a new class from another
Inheritance
For example, we can create a new kind of student called, GraduateStudent.
GraduateStudent behaves in the same way as the student class, but is able to teach some courses.
So we extend the Student class to create a new GraduateStudent class as such:
class GraduateStudent(Student):
def teach_class(self, course): # ...
Inheritance
The Class GraduateStudent is now a SubClass of Student Class.
The Student class is now a SuperClass of the GraduateStudent class.
Inheritance
Now the GraduateStudent has all the variables and functions that are part of the Student class.
We also added a teach_class function that is unique to the GraduateStudent
We don’t have to redefine the register_course or drop_course functions, we can just use them!
With improved reusability, ability for a development team to coordinate improves
Creating an Instance
# Create a Student Instance where the name variable will be set
# to mohammed, and the id variable set to 1234
s1 = Student("mohammed",1234)
# Now we can use the functions
s1.register_course(course)
print(s1.name) # will print mohammed
Creating an Instance of a SubClass
# The GraduateStudent subclass uses the same constructor
s2 = GraduateStudent("Abdullah",2345)
# But has the additional method we defined
s2.teach_course(course)
# Methods from Student class can also be used
s2.teach_course(grad_course)
# Properties from Student class also exist
print(s2.name) # will print abdullah
Extending Methods in SubClasses
If we want to change the implementation of methods in subclasses, just redefine them, this includes the constructor:
class GraduateStudent(Student):
def __init__(self, name, sid):
# redefine the constructor to do something different here
self.thesis_title = #....
self.name = name
self.sid = sid
def teach_class(self, course): # ...
GraduateStudent will use the newly defined constructor
Using super
When redefining methods, you can even reuse the method from the SuperClass:
class GraduateStudent(Student):
def __init__(self, name, sid):
# This will execute the same method from the super class
super().__init__(name, sid)
# Then you can do additional stuff
# specific for GraduateStudents
self.thesis_title = #....
def teach_class(self, course): # ...
GraduateStudent will use the newly defined constructor but execute the Student constructor first.
Is OOP Really Useful?
Anything you can build with OOP you can build with regular structured programming
We did mention that OOP makes code more reusable and improves team collaboration
We will use Inheritance heavily with Django to reconfigure parts of Django for our needs
Without OOP the configurations that we need to do would become much more complex
Is OOP Really Useful?
Another improvement brought by OOP is how we think about System Analysis and Design
Now we try to group related functionality and data together
We think about code organization at analysis and design stage
Contemporary tools for visualizing SAD information builds heavily on OOP (e.g., UML)
Even if you do not turn out to be a programmer understanding OOP will be critical for MIS majors.
Other Useful Tip
You can change what message is displayed if an object of a class was printed by redefining the special __str__ method.
For example:
s1 = Student("mohammed",1234)
print(s1)
# will display:
# <__main__.Student object at 0x7fb768be4910>
Redefining The str Method
Let’s add the __str__ method that just returns a string.
We can use fstrings and reference instance variables using self.
Notice here we want to include the name and if stored in the object:
class Student:
#..
def __str__(self):
return f"<Student {self.name} {self.id}>"
#..
The Output
Now printing the Student object will give a different output:
s1 = Student("mohammed",1234)
print(s1)
# will display:
# <Student mohammed 1234>