-
Notifications
You must be signed in to change notification settings - Fork 0
OBJECT ORIENTED PROGRAMMING
Programs designed around functions are called procedure oriented programms
while those designed around classes are called object oriented.
It's a programming paradigm that uses objects and classes in programming.
The main concept of OOP is to bind data and the functions that work with that
data together as a single unit so that no other part of the code can access this data.
-
Class: A class is a template for creating objects. It contains methods and attributes
that define the behavior of the objects created from the class. -
Object: An object is an instance of a class. It's a real world entity that has attributes
and behaviors. Objects can store data using ordinary variables that belong to the object called 'fieldsorattributes -
Attribute: A variable defined inside a class. It is used to store informaion about the object. -
Method: A method is a function that is defined inside a class. It is used to perform some action or calculation on the object. -
Inheritance: A way to create a new class that is a modified version of an existing class. This new class is called thederived classand the existing class is thebase class -
Polymorphism: It is the ability of a class to take on multiple forms. It's achieved in Python through inheritance and method overloading. -
Encapsulation: The idea of building data and methods that operate on that data within a single unit(object). This is done to protect the data from outside access and modification. -
Data Abstraction: The process of exposing only the essential features of an object but huding its implementation details. It's a way of simplifying complex systems.
These terminology help to differenciate between Independent functions and variables and those that belong to a class or object.
To create a class in Python, you use the class keyword followed by the name of the class and a colon. The class definition should be indented, and the methods and attributes of the class should be defined inside the class definition.(Body of the class)
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
def bark(self):
print("Woof!")
The class defines a Dog class with two attributes: name and breed and a method called bark.
To create an object from a class, you use the class name followed by parentheses and any necessary arguments. For example:
dog1 = Dog("Fido", "Labrador")
dog2 = Dog("Buddy", "Poodle")
This creates two Dog objects, dog1 and dog2 with attributes name and breed set to "Fido" and "Labrador" for dog1, and "Buddy" and "Poodle" for dog2.
In OOP, an attribute is avariable defined inside a class. It is used to store information about the object. There are two types of attributes.
variables that are unique to each instance(object) of a class. alsocalled object variables.
They are defined inside the constructor method (__init__) and are used to store information that is specific to each object. For example, if you have a Person class, each person object might have a unique name and age, which would be stored as instance attributes.
class Person:
def __init__(self, name, age):
self.name = name # instance attribute
self.age = age # instance attribute
p1 = Person("Alice", 30)
p2 = Person("Bob", 35)
In this example, name and age are instance attributes of the Person class. The name attribute of p1 is "Alice" and the age attribute is 30, while the name attribute of p2 is "Bob" and the age attribute is 35.
also called class variables.
They are variables that are shared by all instances of a class.
They are defined outside the constructor method and are the same for all objects.
There is only one copy of the class variable and when any object makes changes to a class variable, that change will be seen by all the other instances.
An object variable with the same name as a class variable will vide the class variable.
Example:
class Car:
make = "Toyota" # class attribute
model = "Corolla" # class attribute
def __init__(self, year):
self.year = year # instance attribute
c1 = Car(2010)
c2 = Car(2015)
In this example, make and model are class attributes of the Car class, and year is an instance attribute. The make and model attributes are shared by all Car objects, while the year attribute is unique to each object.
In Python, instance variables are considered public by default, which means they can be accessed and modified from outside the class.
class Person:
def __init__(self, name, age):
self.name = name # public instance variable
self.age = age # public instance variable
person = Person("John", 30)
print(person.name) # prints "John"
They don't have any special prefixes or suffixes. These instance variables can be accessed or modified from outside the Person class using the dot notation.
Instance variables are variables that are associated with an instace of a class. In python you can make an instance variable private by adding a double underscore prefix to its name. This is the convention used to indicate that the instance variable should not be directly accessed or modified from outside the class.
Example:
class Person:
def __init__(self, name, age):
self.__name = name # private instance variable
self.__age = age # private instance variable
person = Person("John", 30)
print(person.__name) # this will raise an AttributeError
These instance variables can only be accessed or modified from within the Person class using setter and getter methods.
It's worth noting that the double underscore prefix does not actually make the instance variables completely private in Python. It only renames the instance variables to include the class name as a prefix, which makes it more difficult to access them from outside the class. However, the instance variables can still be accessed using the _classname__variablename notation.
print(person._Person__name) # prints "John"
object._classname__variablename notation
Although it's possible to access private instance variables using the _classname__variablename notation, it's generally considered bad practice to do so. Private instance variables are meant to be an implementation detail of the class and should not be accessed or modified directly from outside the class.
class variables are variables that are associated with a class and are shared among all instances of the class. In Python, you can make a class variable private by adding a double underscore prefix to its name. This is a convention used to indicate that the class variable should not be directly accessed or modified from outside the class.
Example:
class Person:
# private class variable
__total_count = 0
def __init__(self, name, age):
self.name = name
self.age = age
Person.__total_count += 1
person1 = Person("John", 30)
person2 = Person("Jane", 25)
print(Person.__total_count) # this will raise an AttributeError
In Python, class variables are considered public by default, which means they can be accessed and modified from outside the class.
Class methods have one specific difference from ordinary functions. They have an extra first argument that has to be added to the beginning of the parameter list. But you do not give a value for this parameter when you call the method. Python will provide it.
It is a special variable that refers to the current instance of a class. It is used to access the attributes and methods of the current object from within the class. by convention it is called self but you could call it anything.
Example:
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
def bark(self):
print("Woof!")
The __init__ method takes three arguments: self, name and breed but when its called during the creation of an object only name and breed are provided.
dog1 = Dog("Fido", "Labrador")
similarly, the bark function takes one parameter self but when calling the function, no arguments are provided.
dog1.bark() # prints "Woof!"
This is because when the method is called, its automatically converted to:
Dog.bark(dog1)
and
Dog.__init__(dog1, name, breed)
The self argument is not specified when calling the method, but it is automatically passed to the method when it is called.
In object-oriented programming (OOP), a method is a function that is defined inside a class. It is used to perform some action or calculation on the object. There are several types of methods in OOP, including instance methods, class methods, and static methods.
These are functions that operate on a specific instance of a class.
They are defined inside the class definition and and take self as an argument which refers to the current instace of the object.
These are functions that operate on the class itself rather than on a specific instance of the class. They are defined using the @classmethod decorator and they take cls as the first argument which refers to the class itself.
These are functions that are associated with a class, but they do not operate on the class or on the instance of the class. They are defined using the @staticmethod decorator and they do not take any special arguments.
Example:
class Dog:
# class attribute
species = "Canis familiaris"
def __init__(self, name, breed):
# Instance attribute
self.name = name
self.breed = breed
# instance method
def say_hi(self):
print("Hello, my name is {} and my breed is {}".format(self.name, self.breed))
@classmethod
def get_species(cls): # class method
return cls.species
@staticmethod
def bark(): # static method
print("Woof!")
N/B: You must refer to the variables and methods of the same object using the self only. This is called attribute reference.
In Python, methods are considered public by default, which means they can be called from outside the class.
In Python, you can make a method private by adding a double underscore prefix to its name. This is a convention used to indicate that the method should not be directly called from outside the class.
Private methods are meant to be an implementation detail of the class and you should use public methods to access and modify private methods.
Example:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# private method
def __increment_age(self):
self.age += 1
# public method
def birthday(self):
self.__increment_age()
person = Person("John", 30)
person.__increment_age() # this will raise an AttributeError
person.birthday()
print(person.age) # prints 31
In the example above, the __increment_age method is private and can only be called from within the Person class. The birthday method is public and can be called from outside the Person class. When the birthday method is called, it calls the private __increment_age method to increment the person's age by one.
By using public methods to access and modify private methods, you can encapsulate the implementation details of the class and provide a more intuitive and user-friendly interface to the users of the class.
These are special methods in Python that are used to implement operator overloading.
They are called "magic methods" because they are not visible to the user, but they are called begind the scenes to perform certain actions.
Magic methods are defined with a double underscore prefix and a double underscore suffix, such as __init__ or __add__. They are used to define the behavior of certain operators, such as the + operator or the [] operator, when they are applied to objects of a class.
Examples:
-
__init__: This is the constructor method, which is called when an object is created(instantiated) from a class. It is used to iniialize the attributes of the object. -
__str__: This method is called when thestr()function is applied on an object of a class. This should return the string representation of the object. -
__len__: This method is called when thelen()function is applied to an object of the class. It should return the length of the object. -
__add__: This method is called when the+operaor is applied to two objects of a class. It should return the result of the addition. -
__getitem__: This method is called when the[]operator is applied to an object of a class. It should return the element at the specified index. -
__repr__: This method is called when therepr()function is applied to an object. It should return a string representation of Python code needed to rebuild the object isingeval(). -
__setitem__: This method is called when an object is indexed and assigned a value such asobject[key] = value. It should set the value at he specified index. -
__delitem__: This method is called when an object is indexed and deleted such asdel object[key]. It should delete the value at the specified index. -
__contains__: This method is called when theinkeyword is used to check if an object is contained in another object. It should returnTrueif the value is contained in the object otherwiseFalse. -
__iter__: This method is called when an object is iterated over, such as in a for loop. It should return an iterator object. -
__del__: This method is used to clean up resources when an object is deleted. It is called automatically when an object is deleted and is used to release resources that the object was using.
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __str__(self):
return f"x = {self.x} and y = {self.y}"
def __repr__(self):
return "Vector({}, {})".format(self.x self.y)
v1 = Vector(1, 2)
v2 = Vector(3, 4)
v3 = v1 + v2 # calls __add__ method
print(v3) # calls __str__ method
# x = 4 and y = 6
repr(v1) # calls __repr__ method
# Vector(1, 2)
v6 = eval(repr(Vector(2, 4))) # eval recreates a new object from the string produced by __repr__
print(str(v6))
# x = 2 and y = 4
A setter is a method that updates the value of an instance variable.
A getter is a method that retrieves the value of an instance variable.
setters and getters are used to give you more control over how instance variables are accessed and modified.
Example:
class Person:
def __init__(self, name, age):
self.__name = name # private instance variable
self.__age = age # private instance variable
# getter method
def get_name(self):
return self.__name
# setter method
def set_name(self, name):
self.__name = name
# getter method
def get_age(self):
return self.__age
# setter method
def set_age(self, age):
self.__age = age
In Python, you can also use decorators to define setters and getters. Here is an example of how to use decorators to define setters and getters:
class Person:
def __init__(self, name, age):
self.__name = name # private instance variable
self.__age = age # private instance variable
# getter decorator
@property
def name(self):
return self.__name
# setter decorator
@name.setter
def name(self, name):
self.__name = name
# getter decorator
@property
def age(self):
return self.__age
# setter decorator
@age.setter
def age(self, age):
self.__age = age
# create an instance of the Person class
person = Person("John", 30)
# retrieve the name using the getter decorator
name = person.name
print(name) # prints "John"
# update the name using the setter decorator
person.name = "Jane"
# retrieve the updated name using the getter decorator
name = person.name
print(name) # prints "Jane"