Encapsulation, inheritance and polymorphism of Python

Encapsulation, inheritance and polymorphism

Object oriented has three characteristics: encapsulation, inheritance and polymorphism

encapsulation

  • Encapsulation means that the implementation code of data and specific operations is placed inside an object, so that the implementation details of these codes are not discovered by the outside world and the internal implementation of the object cannot be modified in any form. It is precisely because of the encapsulation mechanism.
    • Coding platform example code: http://www.ttshitu.com/
  • effect:

    • When a program uses an object, it does not need to care about the details of the data structure of the object and the method of implementing the operation.
    • Using encapsulation can hide the implementation details of the object and make the code easier to maintain. At the same time, it can not directly call and modify the private information inside the object, which ensures the system security to a certain extent.

inherit

  • Inheritance comes from the real world:

    • The simplest example is that children have some characteristics of their parents, that is, each child will inherit some characteristics of their father or mother. Of course, this is only the most basic inheritance relationship. There are more complex inheritance in the real world.
  • In OOP programming, when we define a new class, the new class is called a Subclass, and the inherited class is called a Base class, a parent class, or a Super class.

    • The greatest advantage of inheritance is that while the subclass obtains all the variables and methods of the parent class, it can be modified and expanded as needed. Its syntax structure is as follows:
    • class Father():
          pass
      class Son(Father):
          pass
      
  • Python supports the inheritance mechanism of multiple parent classes.

Inheritance sample code:
# Check whether the subclass (student) can inherit the properties and methods of the parent class (person)
class Person():
    classVar = 'value'
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
    def speak(self):
        print('person can speak')
    @classmethod
    def classFunc(cls):
        print('I am Person classFunc')
    @staticmethod
    def staticFunc():
        print('I am Person staticFunc')

class Student(Person):
    pass

s1 = Student('zhangsan',20,'F')             # Subclasses can inherit the constructor of the parent class
print(s1.name,s1.age,s1.sex)                # Subclasses can inherit instance variables of the parent class
print(Student.classVar)                     # Subclasses can inherit class variables of the parent class
s1.speak()                                  # Subclasses can inherit instance methods of the parent class
Student.classFunc()                         # Subclasses can inherit the class methods and static methods of the parent class
Student.staticFunc()

derive

  • Subclasses add their own unique methods or properties
class Person():
    classVar = 'value'
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
    def speak(self):
        print('person can speak')
    @classmethod
    def classFunc(cls):
        print('i am Person classFunc')
    @staticmethod
    def staticFunc():
        print('i am Person staticFunc')

class Student(Person):
    address = 'beijing'                     # Class variables derived from subclasses themselves
    # How to make subclasses derive their own unique instance variables
    def __init__(self,classNum,score,name,age,sex):
        super().__init__(name,age,sex)      # Call the constructor of the parent class to inherit instance variables from the parent class
        # classNum and score are instance variables derived from subclasses themselves
        self.classNum = classNum
        self.score = score
    # Methods derived from subclasses themselves
    def learning(self):
        pass


s1 = Student(3,100,'zhangsan',20,'sex')     # Subclasses can inherit the constructor of the parent class

Student.classFunc()                         # Subclasses can inherit the class methods and static methods of the parent class
  • super function

    • If you want to force the members of the parent class to be called, how do you implement it? Use the super() function! This is a very important function. The most common function is to call the instantiation method of the parent class through super__ init__!
      • Syntax: Super (subclass name, self) Method name (), what needs to be passed in is the child class name and self. What needs to be called is the method in the parent class. Parameters need to be passed in according to the method of the parent class.
super It usually acts in the construction method of subclasses,In the construction method of subclasses, the super Call the constructor of the parent class,This allows the child class to inherit from the instance variable of the parent class

rewrite

Thinking: what if the methods inherited from the parent class by the subclass can not meet the application of the subclass?
class Father():
    def __init__(self,h):
        self.h = h
    def hobby(self):
        return self.h
    
class Son(Father):
    def __init__(self,h,a1,a2):
        self.a1 = a1
        self.a2 = a2
        super().__init__(h)
    def hobby(self):
        #You can add some operations on the basis of inheriting the original method operations of the parent class
        h_list = super().hobby()
        h_list.append(self.a1)
        h_list.append(self.a2)
        return h_list

Single inheritance

  • Role of inheritance:
  • It realizes the high reuse of the program and greatly shortens the development cycle of the program!
  • Algorithm supplement
    • #:a+b+c=1000,a**2 + b**2 = c**2
      for a in range(1001):
          for b in range(1001):
              c = 1000 - a - b
              if a+b+c == 1000 and a**2 + b**2 == c**2:
                  print(a,b,c)
      
    • How to measure the performance of algorithms: time complexity
      • Time complexity: the number of execution steps of the quantization algorithm
        • Large O notation to represent time complexity:
          • Extract the most meaningful item in the expression (2n+n**2) corresponding to the number of execution steps of time complexity and place it in the brackets after O
          • O(n**2)
    • Sorting algorithm: bubble sorting

      • 1.Compare the size of two elements in the unordered series,Offsets the larger compared elements backward step by step(The largest value in the sequence has been shifted to the last)
        # def sort(alist):
        #     for i in range(len(alist)-1):#Controls the number of pairwise comparisons of elements
        #         if alist[i] > alist[i+1]:
        #             alist[i],alist[i+1] = alist[i+1],alist[i]
        #     return alist
        
        #2. continue the operation of step 1 to act on the first n out of order sequences at one time
        def sort(alist):
            for j in range(len(alist)-1):
                for i in range(len(alist)-1-j):#Controls the number of pairwise comparisons of elements
                    if alist[i] > alist[i+1]:
                        alist[i],alist[i+1] = alist[i+1],alist[i]
            return alist
        alist = [3,8,5,7,6,2,1]
        print(sort(alist))
        
In case of multiple inheritance, you should pay attention to:
  • When a subclass calls a method or variable, it first looks inside itself. If it doesn't, it starts looking in the parent class according to the inheritance mechanism.
  • Find the parent classes one by one in a depth first manner according to the order in the parent class definition of the class!

Example 1: assume the following inheritance relationship:

#B and e classes each have the same show method. After A inherits B and E, it directly calls show. Is the final show executed B or e?
class D():
    pass
class C(D):
    pass
class B(C):
    def show(self):
        print('B()->show')

class G():
    pass
class F(G):
    pass
class E(F):
    def show(self):
        print("E()->show")

class A(B,E):
    pass

A().show()
so, in the definition of A, inheritance parameters are written in order, and those written earlier are inherited first.

What if B does not have the show method, but D does?

class D():
    def show(self):
        print('D()->show')
class C(D):
    pass
class B(C):
    pass

class G():
    pass
class F(G):
    pass
class E(F):
    def show(self):
        print("E()->show")

class A(B,E):
    pass

A().show()
The left side has depth priority. When one road is dark and can not be found, change to another road.

Example 2:

What if the inheritance structure is like this? Class D and class G also inherit class H. When only B and E have the show method, it is no doubt the same as the above example. If B is found, it will not be found. Print "i am B" directly. But what if only h and E have show methods?
class H():
    def show(self):
        print('H()->show')
class D(H):
    pass
class C(D):
    pass
class B(C):
    pass

class G(H):
    pass
class F(G):
    pass
class E(F):
    def show(self):
        print("E()->show")

class A(B,E):
    pass

A().show()

We took it for granted that we would print "i am H" because depth is the priority. However, i am E is printed! Why? In this case, the Python search path is as follows:

What about more complex inheritance situations?

The above two inheritance diagrams are not too difficult, nor can they represent all! In fact, other inheritance patterns can be divided into the above two cases after careful dissection

type and isinstance

  • isinstance() function to determine whether an object is a known type, similar to type().

  • Syntax of isinstance() method:

    • isinstance(object, classinfo)
      Parameters:
          object -- Instance object.
          classinfo -- It can be a class name, a primitive type, or a tuple of them.
      Return value:
      		If the type of object is the same as that of parameter 2( classinfo)Return if the same True´╝îOtherwise return False. 
      
    • #Basic use of isinstance and type
      
  • Type: returns the type of the object

  • The difference between isinstance() and type():

    • type() does not consider a subclass to be a parent type and does not consider inheritance.
    • isinstance() will consider the subclass as a parent type and consider the inheritance relationship.
    • class A():
          pass
      class B(A):
          pass
      a = 10
      b = B()
      print(type(a),isinstance(a,int))
      #It is considered that in object-oriented, a subclass object can be regarded as a parent type
      print(type(b),isinstance(b,A))
      

Difference between ce() and type():

  • type() does not consider a subclass to be a parent type and does not consider inheritance.
  • isinstance() will consider the subclass as a parent type and consider the inheritance relationship.
  • class A():
        pass
    class B(A):
        pass
    a = 10
    b = B()
    print(type(a),isinstance(a,int))
    #It is considered that in object-oriented, a subclass object can be regarded as a parent type
    print(type(b),isinstance(b,A))
    

Tags: Python programming language

Posted by Guardian-Mage on Sat, 04 Jun 2022 02:51:26 +0530