Uncle Niu talks about Python Chapter 14: explain the inheritance and instances of Class (take the king as an example)

Posted by yoda69 on Sat, 22 Jan 2022 05:30:34 +0100

Uncle calf takes you across the threshold of Python class easily

1. Boastful inheritance

The best example of inheritance turns out to be virus replication. COVID-19 COVID-19 is rampaging around the world. The delta variant has triggered a new epidemic because of its more powerful transmission. Even China's city has not been spared. The process of virus replication and mutation is the process that the next generation inherits some characteristics of the previous generation and develops new characteristics (as shown in the figure below).

Virus variation comes from DNA(RNA) protein mutation, so inheritance in programming also has the following two characteristics:

  1. Copy the characteristics of the previous generation (i.e. properties and methods)
  2. Develop new features (i.e. attributes and methods)

2. Hierarchy and reuse

Class can be regarded as the DNA of a virus (code), so defining a new class is equivalent to generating a new virus. The process of creating an instance from a class is similar to the self replication of a virus to produce many viruses with the same DNA. Class inheritance is equivalent to the variation of this DNA during replication, The process of producing new kinds of viral DNA or the DNA of virus variants.

The "inheritance" process in the program must usually be explicitly declared manually by the program (of course, it does not rule out the existence of programs that can replicate and mutate themselves: -). Suppose we are making NPC roles for games similar to the glory of the king. In order to reuse the characteristics of roles, we can organize various roles in a hierarchical relationship. Each node in the figure is a class:

Game character inheritance


In this inheritance relationship, all NPCs can share the same underlying logic: share various attributes, such as health value and attack ability (although individual values are different, they have the same name); And they can share the same behaviors (i.e. methods), such as attacks. No matter what NPC attacks, it can reduce the health of the other party.

Looking at the second layer in the figure above, Xiaobing inherits from NPC and can develop its own features for reuse by the Class in the next layer. For example, small soldiers can add the behavior of "walking" (i.e. method), which allows small soldiers to move along the path of the military line. No matter what soldiers (as long as they are derived from "small soldiers"), they should (or can) share this behavior.

3. Basic examples

Next, we will implement the two classes in the figure above: NPC and Soldier. The relationship is shown in the figure below:

Blue is an added feature, green is a method, and red is an inherited feature.

Inheritance relationship of elements in class

The following code implements the inheritance of the above classes. First define the most basic NPC class and Soldier class as follows:

class Npc:

    def __init__(self,name):   #The initialization method self (the first positional parameter of the method) represents an instance of this class
        self.name = 'NPC' #The initial name is NPC
        self.life = 100   #The initial health value is 100
        self.harm = 2     #The initial damage is 2

    def __str__(self):    #The string value returned when the instance is converted to a string
        return '%s %d'%(self.name,self.life)  #When an instance of this class is returned, the name and life value are printed

    def attack(self,other): #The attack reduces the health of others and passes "other" as a parameter
        print(self.name,'attack',other.name,'-%d'%self.harm)
        other.life -= self.harm


class Soldier(Npc):
    def __init__(self,name):
        super().__init__(name)      #Call the upper initialization function and use the initialization code of the parent class
        self.name = name            #Soldier's name
    

From the analysis of the definition of the Npc class (refer to the definition of the class introduced earlier), it is obvious that this class has three attributes: life (Health), harm (damage) and name (name), and has attack behavior (method).

Inheritance syntax: when defining a subclass Soldier, you can directly use parentheses after the class name Soldier. This class does not generate a new attribute, but uses the passed in name to overwrite the original name attribute. Note the following expression:

        super().__init__(name)          #Call the upper initialization function and use the initialization code of the parent class

The expression super() refers to the list of parent classes. This statement calls the initialization function of the parent class NPC, which explicitly inherits the three attributes of NPC: life, harm and name. In other cases, if there are parent classes, they will be arranged in MRO order. The following articles are devoted to MRO, which can be referred to:

Yue Xing: Python super() function 40.6 comment articlehttps://zhuanlan.zhihu.com/p/28340924

4. Reuse parent class methods

There is no attack method defined in the above Soldier class, but attack is defined in its parent class Npc. Can we use it directly in the subclass? Add and run the following code:

soldier_a = Soldier('Red Square soldier')  #Instantiated soldier a
soldier_b = Soldier('LAN Fangbing')  #Instantiate soldier b
soldier_a.attack(soldier_b)   #The method of parent attack is used
print(soldier_a,soldier_b)    #Print the effect of the attack

The above code generates red and blue soldiers in the game, passes in the name through the initialization method, and calls the attack method through the instance. If this method works, the health value of the attacked blue soldier should be reduced. Run the whole program together and see the following results:

Red attack blue - 2
Red Army 100 blue army 98

You can see that there is no need for any settings. Subclasses can directly use the methods of the parent class, but subclasses must be refactored__ init()__ This function, and use the super() method in the function to create the parent class_ init()__ Create a new instance property.

5. Reconstruct other methods

The Soldier subclass completely reuses the attack method of the parent class, and actually reconstructs the attack method of the parent class__ init()__ Function to get the properties of the parent class. As a game designer, you think this "attack" is too common. If you want to design a more cool "attack", you need to refactor the attack method to add new features.

In order to make readers better understand the reconstruction of the method, we assume that the "super Soldier" has its own "anti armour", that is, when it is attacked, it will cause the other party to lose life while it is injured. Let's see how the attack of the "super Soldier" is written by inheriting the Soldier class? The inherited relationship from NPC - > Soldier - > super Soldier is as follows:

Blue is an added feature, green is a method, and red is an inherited feature.

Inheritance relationship of each element in multi-level inheritance class

Continue to add and run the following code:

class SuperSoldier(Soldier):
    def __init__(self,name):
        self.armHarm = 1                 #Anti armour damage
        super().__init__(name)           #Call the upper initialization function and use the initialization code of the parent class
    
    def attack(self,other):
        super().attack(other)        #Call the attack function of the upper layer and reuse the common attack behavior of the parent class
        if other.armHarm:
            self.life -= other.armHarm
            print(other.name, 'Anti armour injury:',other.armHarm)

super_a = SuperSoldier('Super soldier A')  #Instantiate super soldiers with anti armor
super_b = SuperSoldier('Super soldier B')  #Instantiate super soldiers with anti armor
super_b.attack(super_a)           #Super B attack A
print(super_a,super_b)   

The above code adds the attribute of anti armour damage to super soldiers, and rewrites the attack code. After running, the results are as follows:

Super soldier B Attack super soldier A -2
 Super soldier A Anti armour injury: 1
 Super soldier A 98 Super soldier B 99

It can be seen that although super soldier B attacked A, he also suffered 1 point of damage. By refactoring the functions defined by the parent class in the class and combining with the super() function, we can reuse the old features or add new features for the next generation.

6. Multi class inheritance

Multi class inheritance means that there are multiple parent classes, which can integrate the characteristics of multiple classes. In the king, if you have defeated the dragon, a creature called dominant vanguard will be generated in our army line. As shown below, it not only has the general attributes of soldiers, such as walking route, health and attack power, but also has the fire spitting attack mode of dragon (wild monster).

Multi class inheritance can achieve the effect of combination

Create a new file, copy and paste all the following codes:

class Npc:

    def __init__(self,name):   #The initialization method self (the first positional parameter of the method) represents an instance of this class
        self.name = 'NPC' #The initial name is NPC
        self.life = 100   #The initial health value is 100
        self.harm = 2     #The initial damage is 2

    def __str__(self):    #The string value returned when the instance is converted to a string
        return '%s %d'%(self.name,self.life)  #When an instance of this class is returned, the name and life value are printed

    def attack(self,other): #The attack reduces the health of others and passes "other" as a parameter
        print(self.name,'attack',other.name,'-%d'%self.harm)
        other.life -= self.harm


class Soldier(Npc):
    def __init__(self,name):
        super().__init__(name)          #Call the upper initialization function and use the initialization code of the parent class
        self.name = name            #Soldier's name
    
    def move(self):
        print(self.name,'walk','.'*20)  #Use a point to represent movement

class Beast(Npc):
    def __init__(self,name):
        super().__init__(name)          #Call the upper initialization function and use the initialization code of the parent class
        self.name = name

    def fire(self):
        print(self.name,'Spit fire','*'*20)


class Pioneer(Soldier,Beast):
    def __init__(self,name):
        super().__init__(name)          #Call the upper initialization function and use the initialization code of the parent class


p = Pioneer('Master pioneer 1')
print(p)
p.move()
p.fire()

See the running results after running:

Master pioneer 1 100
 Master pioneer 1 walk ....................
Master pioneer 1 spit fire ********************

By inheriting the two classes, the master Pioneer has the function of walking (only defined in the parent class Soldier) and spitting fire (only defined in the parent class Beast), and has various properties of the most primitive NPC.

The above is the content of class object inheritance in this article. The core concept of class is reuse. Generally, experts write programs from the most abstract class, write the most easily shared code first, and write programs from top to bottom.

It's not easy for uncle Niu to write and draw. Remember to praise him.

The inheritance of this section, if you are happy, remember to share it with other students.

Topics: Python Back-end