Object Oriented Programming

 
        Solving a problem by creating objects is on of the most popular approaches in programming. This is called OOP.
        This concept focuses on using reusable code, which implements DRY principle

oop


Class :  A class is a blueprint for creating objects.

syntax: 

Class Emp :
#methods and variables

Object:  Object is an instantiation of a class. when class is defined, a template (info) is defined. memory is allocated only after object instantiation.
Objects of a given class can invoke the methods available to it without revealing the implementation details to the user. : Abstraction and Encapsulation

Modelling a problem in OOP's : we identify the following in our program

Noun : class : Emp
Adjective : Attributes : name, age
Verbs : Methods : getsal(), inc()

Class Attributes : An attribute that belongs to the class rather than a particular object.

Class Emp :
company = "google" :  [specific to each class]
praveen = Emp() : [object instantiation]
praveen.company
Emp.company = "YouTube" : [changing class attribute]

Instance Attributes : an attribute that belongs to the Instance (object) assuming the class from the previous example :

praveen.name = "praveen"
praveen.salary = "50k" : [adding instance attributes]

***Instance attributes take preference over class attributes during assignment and retrieval.

self parameter:  self refers to the instance of the class. Itis automatically passed with a function call from an object.

praveen.getsal() : here self is praveen and equivalent to Emp getal(praveen)

The function getsal is defined as :

Class Emp :
company = "Google"
def getsal(self) :
print("Salary not mentioned")

Static Method :  Sometimes we need a function that doesn't use the self parameter. we can define a static method :

@staticmethod           : [decorator to mark greet as a static method]
def greet() :
print("hello user")

--init-- () constructor :  is a special method wi=hich is first run as soon as the object is created. this method is also known as constructor. it takes self arguement and can also take further arguements.

Class Emp :
def --init-- (self, name) :
self. name = name
def getsal(self) :
....
praveen = Emp ("praveen")   : [Object can be instantiated using constructor]

Programs :

1. #oop's concept

class Number:
    def sum(self):
        return self.a + self.b

num = Number()
num.a = 12
num.b = 34
s = num.sum()
print(s)

# a = 12
# b = 34

# print("The sum of a and b is ", a+b)

'''
PascalCase 
EmployeeName -->PascalCase 

camelCase
isNumeric, isFloatOrInt -->camelCase
'''

2. #game example

class Remote():
    pass

class Player:
    def moveRight(self):
        pass

    def moveLeft(self):
        pass

    def moveTop(self):
        pass

remote1 = Remote()
player1 = Player()

if(remote1.isLeftPressed()):
    player1.moveLeft()

3. #Employee example

class Employee:
    company = "Google"
    salary = 100

praveen= Employee()
rajni = Employee()
praveen.salary = 300
rajni.salary = 400

print(praveen.company)
print(rajni.company)
Employee.company = "YouTube"
print(praveen.company)
print(rajni.company)
print(praveen.salary)
print(rajni.salary)

4. #instance class attribute

class Employee:
    company = "Google"
    salary = 100

praveen = Employee()
rajni = Employee()

# Creating instance attribute salary for both the objects
# praveen.salary = 300
# rajni.salary = 400
praveen.salary = 45
print(praveen.salary)
print(rajni.salary)

# Below line throws an error as address is not present in instance/class 
# print(rajni.address)

5. #Self

class Employee:
    company = "Google"
    def getSalary(self):
        print(f"Salary for this employee working in {self.company} is {self.salary}")

praveen = Employee()
praveen.salary = 100000
praveen.getSalary() # Employee.getSalary(harry)

6. #static method

class Employee:
    company = "Google"

    def getSalary(self, signature):
        print(f"Salary for this employee working in {self.company} is {self.salary}\n{signature}")

    @staticmethod
    def greet():
        print("Good Morning, Sir")

    @staticmethod
    def time():
        print("The time is 9AM in the morning")

praveen = Employee()
praveen.salary = 100000
praveen.getSalary("Thanks!") # Employee.getSalary(harry)
praveen.greet() # Employee.greet()
praveen.time()

7. #constructor

class Employee:
    company = "Google"

    def __init__(self, name, salary, subunit):
        self.name = name
        self.salary = salary
        self.subunit = subunit
        print("Employee is created!") 

    def getDetails(self):
        print(f"The name of the employee is {self.name}")
        print(f"The salary of the employee is {self.salary}")
        print(f"The subunit of the employee is {self.subunit}")

    def getSalary(self, signature):
        print(f"Salary for this employee working in {self.company} is {self.salary}\n{signature}")

    @staticmethod
    def greet():
        print("Good Morning, Sir")

    @staticmethod
    def time():
        print("The time is 9AM in the morning")

praveen = Employee("praveen", 100, "YouTube")
# praveen = Employee() --> This throws an error (missing 3 required positional arguments:)
praveen.getDetails()