Three relationships in Python classes (dependency / composition / inheritance)

In object-oriented, there are three relationships between classes: dependency, composition, and inheritance.

1. Dependency:
The relationship used to pass the class name or object of one class as a parameter to another function is dependency

class People:

    def __init__(self,name):
        self.name = name
    def open(self,bx):
        bx.open_door(self)
    def close(self,bx):
        bx.close_door(self)

class Refrigerator:

    def __init__(self,name):
        self.name = name
    def open_door(self,p):
        print(f"{p.name} Open the refrigerator")
    def close_door(self,p):
        print(f"{p.name} Turn off the refrigerator")


r = People("Big devil")   # The People class instantiates an object r
aux = Refrigerator("Aux")   # Refrigerator class instantiates an object aux
r.open(aux)    # Using the open method that passes the aux object as a parameter to the r object
r.close(aux)   # Use the close method that passes the aux object as a parameter to the r object

2. Combination relationship:
Encapsulating the objects of one class into the properties of the objects of another class is called composition

class Boy:

    def __init__(self,name,g):
        self.name = name    # self = b
        self.g = g         # g is an object memory address instantiated by the girl class
    def eat(self):
        print(f"{self.name}and{self.g.age}year,And{self.g.weight}Kilogram{self.g.name}py Friend.We had a candlelight dinner together!")
    def make_keep(self):
        self.g.live(f"{self.g.weight}Kilogram{self.g.name}to{self.name}Trample back")


class Girl:

    def __init__(self,name,age,sex,weight,*args):
        self.name = name
        self.age = age
        self.sex = sex
        self.weight = weight
        self.args = args
    def live(self,argv):
        print(f"Live content:{argv}")


g = Girl("Jobid",54,"female",220)
b = Boy("Taibo",g)    # Encapsulate the object g as an attribute into the attribute of the b object
b.make_keep()

3. Inheritance relationship

(1) What is object-oriented inheritance

inheritance is a concept in object-oriented software technology. If a class a "inherits" from another class B, this class A is called "the child class of B", and B is called "the parent class of a" or "B is the superclass of a". inheritance can make subcategories have various properties and methods of the parent class without having to write the same code again. While the child class inherits the parent class, some properties can be redefined and some methods can be overridden, that is, the original properties and methods of the parent class can be overridden to obtain different functions from the parent class. In addition, it is common to append new properties and methods to subcategories.

In general, static object-oriented programming languages, inheritance belongs to static, which means that the behavior of subcategories has been determined at compilation time and cannot be expanded at execution time.

(2) In procedure A(B)

<1> A -- subclass, derived class

<2> B -- parent class, base class, superclass

When we write multiple classes, we will find many problems, such as:

class Human:

    def __init__(self,name,age,sex):
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self):
        print("eat")

class Dog:

    def __init__(self, name, age, sex):
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self):
        print("eat")

class Cat:

    def __init__(self, name, age, sex):
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self):
        print("eat")

class Pig:

    def __init__(self, name, age, sex):
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self):
        print("eat")

The above code is repeated. At this time, we can simplify the relevant code as follows:

class Animal: # Parent class
    """
    //Zoology
    """
    live = "Living"

    def __init__(self, name, age, sex):
        print("is __init__")
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self):  # self is the position parameter of the function
        print("eat")

class Human(Animal): # Subclass
    pass

class Dog(Animal):  # Subclass
    pass

class Cat(Animal):  # Subclass
    pass

class Pig(Animal):  # Subclass
    pass

(3) Advantages of inheritance:

  • Reduce duplicate code

  • Clear structure and standard

  • Increase the coupling (the coupling should not be more, in fine)

(4) Inherited categories:

<1> Single inheritance

<2> Multiple inheritance

Python 2: before python2.2, there were classic classes. After python2.2, there are new classes. Inheriting object is the new class
Python 3: only new classes, whether you inherit or not, are new classes

(5) Single inheritance:

<1> Use the properties and methods of the parent class through the class name of the child class

'''
//No one answers the questions? Xiaobian created a Python learning exchange QQ group: 579817333 
//Looking for like-minded small partners, mutual help, there are good video learning tutorials and PDF ebooks in the group!
'''
class Animal: # Parent class

    live = "Living"

    def __init__(self, name, age, sex):
        print("is __init__")
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self):  # self is the position parameter of the function
        print("eat")

class Human(Animal): # Subclass
    pass

class Dog(Animal):  # Subclass
    pass
    
Human.eat(12)
Human.__init__(Human,"Big devil",18,"male")

print(Human.live)
print(Human.__dict__)

<2> Use the properties and methods of the parent class through the objects of the child class

class Animal: # Parent class

    live = "Living"

    def __init__(self, name, age, sex):
        print("is __init__")
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self):  # self is the position parameter of the function
        print("eat")

class Human(Animal): # Subclass
    pass

class Dog(Animal):  # Subclass
    pass
    
p = Human("Big devil",18,"male")
d = Dog("remmom",1,'mother')
print(d.__dict__)
print(p.__dict__)

p = Human("Big devil",18,"male")
print(p.live)

(6) Search order:

<1> Irreversibility (principle of proximity)

<2> Use the properties or methods of the parent class (search order) by subclass and class name: current class, parent class of the current class, parent class of the parent class of the current class ----- >

<3> Use the properties or methods (search order) of the parent class through the child class object: first find the object, instantiate the class of the object, and the parent class of the current class -- >

(7) Use both child and parent methods or properties:

<1> Method 1: independent (unnecessary) inheritance

class Animal: # Parent class

    live = "Living"

    def __init__(self, name, age, sex):
        # Self = memory address of P
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self):  # self is the position parameter of the function
        print("eat")

class Human: # Subclass

    def __init__(self, name, age, sex, hobby):
        # print(Animal.live)
        # Self = memory address of P
        Animal.__init__(self,name,age,sex)  # Directly use the Animal class to call methods in the Animal class
        self.hobby = hobby

class Dog:

    def __init__(self, name, age, sex, attitude):
        # Self = memory address of P
        self.name = name
        self.sex = sex
        self.age = age
        self.attitude = attitude      # Compare with Human class


p = Human("Big devil",18,"male","Bodybuilding")
print(p.__dict__)

<2> Method 2: dependency (need) inheritance

class Animal: # Parent class

    live = "Living"

    def __init__(self, name, age, sex):
        # Self = memory address of P
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self):  # self is the position parameter of the function
        print("eat")
        
   class Dog(Animal):

    def __init__(self, name, age, sex, attitude):
        # Self = memory address of P
        # super(Dog,self).__init__(name,age,sex)   # Complete writing
        super().__init__(name,age,sex)   # Normal writing  # Using the methods in the parent class through the super method
        self.attitude = attitude

d = Dog("Big devil",18,"male","loyal")
print(d.__dict__)

Exercises:

class Base:
    def __init__(self, num):   
        self.num = num

    def func1(self):
        print(self.num)
        self.func2()

    def func2(self):
        print("Base.func2")

class Foo(Base):
    def func2(self):
        print("Foo.func2")

obj = Foo(123)
obj.func1()
class Base:
    def __init__(self, num):
        self.num = num

    def func1(self):
        print(self.num)
        self.func2()

    def func2(self):
        print(111, self.num)

class Foo(Base):
    def func2(self):
        print(222, self.num)

lst = [Base(1), Base(2), Foo(3)]
for obj in lst:
    obj.func1()

(8) Multiple inheritance

Multiple inheritance is to inherit multiple parent classes

In multiple inheritance, there are such problems. When there is a double name method in two classes, it will involve how to find the MRO(method resolution order) problem. In Python, this is a very complex problem. Because in different versions of python, different algorithms are used to complete MRO

(1) Classic class: execute from left to right in multiple inheritance

class A:
    name = "Xiao Bao"

class B(A):
    name = "Taibo"

class C(A):
    name = "marry"

class D(B, C):
    name = "Magic 22"

class E:
    name = "Magic 11"

class F(E):
    name = "magic"

class G(F, D):
    name = "bb"
    
class H:
    name = "aaa"

class Foo(H, G):
    pass

f = Foo()
print(f.name)

#  The result is aaa

Summary:

Classic class: (depth first) left first, a road to the end, can not find will return to the starting point right query

(2) New class: using c3 algorithm (it is also said that using breadth first -- imprecise)

# The following example runs in Python 2.7
class O(object):
    name = "Xiao Bao"

class D(O):
    name = "Heaven devil"

class E(O):
    name = "Taibo"

class F(O):
    name = "marry"

class B(D,E):
    pass

class C(E,F):
    name = "Peter Jackson's King Kong"

class A(B,C):
    pass

a = A()
print a.name

#  It turns out to be a demon

(3) Core mro of c3 algorithm

<1> MRO () -- a method provided by Python to view the execution order of multiple inheritance

<2> MRO is a sequence table L, which is calculated when the class is created. The general calculation formula is:

mro(Child(Base1,Base2)) = [ Child ] + merge( mro(Base1), mro(Base2), [ Base1, Base2] )
(where Child inherits from Base1, Base2)

If it inherits to a base class: class B(A), then the mro sequence of B is

mro( B ) = mro( B(A) )
= [B] + merge( mro(A) + [A] )
= [B] + merge( [A] + [A] )
= [B,A]

If you inherit more than one base class: class B(A1, A2, A3 )mro sequence of B

mro(B) = mro( B(A1, A2, A3 ...) )
= [B] + merge( mro(A1), mro(A2), mro(A3) ..., [A1, A2, A3] )
= ...

The calculation result is a list. At least one element in the list is the class itself, as shown in the above example [A1,A2,A3]. merge operation is the core of C3 algorithm.

<3> Head and tail

Header: first element of list

Footer: set of elements outside the header in the list (can be empty)

Example list: [A, B, C] header is A, footer is B and C

<4> + actions between lists

+Operation:

[A] + [B] = [A, B] (omitted by default in the following calculation)---------------------

Example of merge operation:

For example, calculate merge ([e, O], [C, e, F, O], [C])
There are three lists: ① ② ③

1. The merge is not empty. Take the header E of the first list (1) for judgment                              
   The tail of each list is [O], [E,F,O], and E is in the set of tail, thus skipping the current list
 2 take out the head C of list ② and judge
   C is not in the collection of each list, so take C out of the merge and delete it from all headers
   merge( [E,O], [C,E,F,O], [C]) = [C] + merge( [E,O], [E,F,O] )
3. Perform the next new merge operation
---------------------

<5> mro cannot be used for classic classes, but only for new classes

Tags: Python Attribute Programming

Posted on Mon, 20 Apr 2020 09:37:59 -0700 by bUcKl3