Thursday, September 16, 2021

Python (5): OOP Concepts



OOP Concepts

P: Polymorphism I: Inheritance E: Encapsulation A: Abstraction Apple PIE

How and where OOP concepts are used?

Because using classes well requires some up-front planning, they tend to be of more interest to people who work in strategic mode (doing long-term product development) than to people who work in tactical mode (where time is in very short supply).

The concept of “self”

class C2: pass # Make superclass objects class C3: pass class C1(C2, C3): # Make and link class C1 def setname(self, who): # Assign name: C1.setname self.name = who # Self is either I1 or I2 I1 = C1() # Make two instances I2 = C1() I1.setname('bob') # Sets I1.name to 'bob' I2.setname('sue') # Sets I2.name to 'sue’ print(I1.name) # Prints 'bob' There’s nothing syntactically unique about def in this context. Operationally, though, when a def appears inside a class like this, it is usually known as a method, and it automatically receives a special first argument—called self by convention—that provides a handle back to the instance to be processed. Any values you pass to the method yourself go to arguments after self (here, to who). If you’ve ever used C++ or Java, you’ll recognize that Python’s self is the same as the “this” pointer, but self is always explicit in both headers and bodies of Python methods to make attribute accesses more obvious: a name has fewer possible meanings.

Concept of Inheritance of Variables and Methods

class Employee: # General superclass def __init__(self, who = "NA", sal = 0): # Set name when constructed self.name = who self.salary = sal def getDetails(self): rtn = (self.name, self.salary) print("rtn: ", rtn) return rtn class Engineer(Employee): # Specialized subclass pass print("Defaults:") e = Engineer() e.getDetails() print() print("Custom:") e = Engineer(who = 'Ashish', sal = 100) e.getDetails() $ python inheritance.py Defaults: rtn: ('NA', 0) Custom: rtn: ('Ashish', 100)

Error Alert

class Employee: # General superclass def __init__(self, who, sal): # Set name when constructed self.name = who self.salary = sal class Engineer(Employee): # Specialized subclass pass e = Engineer() $ python inheritance.py Traceback (most recent call last): File "inheritance.py", line 14, in <module> e = Engineer() TypeError: __init__() missing 2 required positional arguments: 'who' and 'sal'

Polymorphism

class Employee: def __init__(self, who = "NA", sal = 0): self.name = who self.salary = sal def getDetails(self): rtn = (self.name, self.salary) print("rtn: ", rtn) return rtn class Engineer(Employee): def reviseSalary(self): self.salary =+ 100 def reviseSalary(self, inc = 200): self.salary =+ inc e = Engineer(who = 'Ashish', sal = 100) e.getDetails() e.reviseSalary() e.getDetails() e.reviseSalary(inc = 500) e.getDetails() $ python polymorphism.py rtn: ('Ashish', 100) rtn: ('Ashish', 200) rtn: ('Ashish', 500)

Abstraction

When we call "print()" for an object it prints some object details like these: <__main__.Employee object at 0x000001F549F7A1D0> However, when we define the Python's in-built __str__() for an object, we are essentially telling what should happen when print() is called for the object and end-user would not have to know how to get user-friendly details of the object. This is abstraction (abstraction of print()'s output in __str__() redefining it). class Employee: def __init__(self, who = "NA", sal = 0): self.name = who self.salary = sal def getDetails(self): rtn = (self.name, self.salary) print("rtn: ", rtn) return rtn class Engineer(Employee): def reviseSalary(self): self.salary =+ 100 def reviseSalary(self, inc = 200): self.salary =+ inc def __str__(self): # Higher priority than __repr__ when using with print() return '[From __str__: %s, %s]' % (self.name, self.salary) #def __repr__(self): # return '[From __repr__: %s, %s]' % (self.name, self.salary) e = Engineer(who = 'Ashish', sal = 100) e.getDetails() print("e:", e) print("e.__repr__():", e.__repr__()) f = Employee() print("f = Employee():", f) $ python abstraction.py rtn: ('Ashish', 100) e: [From __str__: Ashish, 100] e.__repr__(): <__main__.Engineer object at 0x000001F549C2F8D0> f = Employee(): <__main__.Employee object at 0x000001F549F7A1D0>
Tags: Python,Technology, Title: Python (5): OOP Concepts

No comments:

Post a Comment