Python object-oriented programming - Inheritance and derivation

Python object-oriented programming - Inheritance and derivation

First, the initial inherited

1. What is inherited

Inheritance refers to the relationship between class and class, it is a kind 什么“是”什么of relationship, one of the successor function is used to solve the problem of code reuse.

Inheritance is a way to create a new class, in python, the new class can inherit one or more parent classes, parent and can become a base class or super class, the new class is called the derived class or subclass

2, python class inheritance is divided into: single and multiple inheritance

class ParentClass1: #定义父类
    pass

class ParentClass2: #定义父类
    pass

class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
    pass

class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
    pass

3, view the inherited

>>> SubClass1.__bases__ #__base__只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类
(<class '__main__.ParentClass1'>,)
>>> SubClass2.__bases__
(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)

4, Classic and new-style class

1.只有在python2中才分新式类和经典类,python3中统一都是新式类
2.在python2中,没有显式的继承object类的类,以及该类的子类,都是经典类
3.在python2中,显式地声明继承object的类,以及该类的子类,都是新式类
4.在python3中,无论是否继承object,都默认继承object,即python3中所有类均为新式类

Note: If you do not specify a base class, python class will inherit the default object class, object class is the base class for all python, which provides some common methods (such as __str__) implementation.

>>> ParentClass1.__bases__
(<class 'object'>,)
>>> ParentClass2.__bases__
(<class 'object'>,)

Second, inheritance and abstract (abstract before re-inherited)

Abstract i.e., extraction or like parts is more like.

Abstract is divided into two levels:

1, Obama and Massey maybe more like objects into categories extracting portion;

2, human, pig, dog three classes comparison image extraction portion into the parent class.

Abstract most important role is divided into categories (you can isolate concerns, reduce complexity)

Inheritance: is based on the abstract result, a programming language to implement it, certainly before undergoing the process of abstraction, in order to express the abstract structure by way of inheritance.

Just an abstract process analysis and design, an action or a skill, you can get through the abstract class.

Third, inheritance and reusability

In the development process of the process, if we define a class A, then you want to build another new class B, but most of the same class A and class B, we can not start from scratch to write a class B, which We use the concept of inheritance of classes.

By way of a new inheritance class B, so that B inherits A, B will 'genetic' all the attributes (data attribute and function attribute) of A, code reuse.

class Hero:
    def __init__(self,nickname,aggressivity,life_value):
        self.nickname=nickname
        self.aggressivity=aggressivity
        self.life_value=life_value

    def move_forward(self):
        print('%s move forward' %self.nickname)

    def move_backward(self):
        print('%s move backward' %self.nickname)

    def move_left(self):
        print('%s move forward' %self.nickname)

    def move_right(self):
        print('%s move forward' %self.nickname)

    def attack(self,enemy):
        enemy.life_value-=self.aggressivity
class Garen(Hero):
    pass

class Riven(Hero):
    pass

g1=Garen('草丛伦',100,300)
r1=Riven('锐雯雯',57,200)

print(g1.life_value) #结果:300
r1.attack(g1)
print(g1.life_value) #结果:243

Note: The class already have established a new class, thus reusing already have the software set most part, saves programming effort, it is often said that software reuse, not only can reuse your own class, others can also be inherited, such as standard libraries to customize the new data types, so is greatly reducing software development cycle of large software development is of great significance.

Fourth, look at the property to find

Like property g1.life_value like references, you will start looking for examples life_value then go to class to find, and then go looking for parent class ... until the top of the parent class. So how do you explain the following print result?

class Foo:
    def f1(self):
        print('Foo.f1')

    def f2(self):
        print('Foo.f2')
        self.f1()

class Bar(Foo):
    def f1(self):
        print('Bar.f1')


b=Bar()
b.f2()

# 打印结果:
# Foo.f2
# Bar.f1

Fifth, derived

Of course, you can also add your own sub-class of new properties or redefine these attributes at your own here (does not affect the parent), to note that, once again define their own attributes and the same name as the parent class, then call new when the property, with regard to the subject himself.

class Riven(Hero):
    camp='Noxus'
    def attack(self,enemy): #在自己这里定义新的attack,不再使用父类的attack,且不会影响父类
        print('from riven')
    def fly(self): #在自己这里定义新的
        print('%s is flying' %self.nickname)

In a subclass, the new function attributes of the same name, the edit function within a function when that function may need to reuse the same name in the parent class functions, should be used to invoke the ordinary functions, namely: the class name .func (), and this time it is no different from the ordinary function call, so even its self argument should be passed by value.

class Riven(Hero):
    camp='Noxus'
    def __init__(self,nickname,aggressivity,life_value,skin):
        Hero.__init__(self,nickname,aggressivity,life_value) #调用父类功能
        self.skin=skin #新属性
    def attack(self,enemy): #在自己这里定义新的attack,不再使用父类的attack,且不会影响父类
        Hero.attack(self,enemy) #调用功能
        print('from riven')
    def fly(self): #在自己这里定义新的
        print('%s is flying' %self.nickname)

r1=Riven('锐雯雯',57,200,'比基尼')
r1.fly()
print(r1.skin)

'''
运行结果
锐雯雯 is flying
比基尼
'''

Sixth, the realization and the principle of inheritance

python in the end is how to achieve inheritance, for each class you define, calculate a python accounting method resolution order (MRO) list, the MRO list is a simple list of all the linear sequence of base classes, for example,

>>> F.mro() #等同于F.__mro__
[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, 
<class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

In order to achieve inheritance, python will start looking from left to right on the MRO base class list until it finds the first match of this property class. This list is constructed MRO is achieved by a linear algorithm C3. We do not go into the mathematical principle of this algorithm, it is actually a list of all the parent class MRO merge and follow the following three criteria:

1, subclass the parent class will first be checked.

2, a plurality of parent classes will be checked in accordance with their order in the list.

3, if there are two legal option for the next class, selecting a first parent.

Only inherit in Java and C # neutron class a parent class, and Python neutron class can inherit more than one parent class at the same time, if more than one parent class inherit, then there are two ways to find properties, namely: depth-first and breadth-first.

Sample code:

class A(object):
    def test(self):
        print('from A')

class B(A):
    def test(self):
        print('from B')

class C(A):
    def test(self):
        print('from C')

class D(B):
    def test(self):
        print('from D')

class E(C):
    def test(self):
        print('from E')

class F(D,E):
    # def test(self):
    #     print('from F')
    pass
f1=F()
f1.test()
print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性

#新式类继承顺序:F->D->B->E->C->A
#经典类继承顺序:F->D->B->A->E->C
#python3中统一都是新式类
#pyhon2中才分新式类与经典类

Seven, call the parent class method in a subclass

In the new method of deriving subclasses, often we need to reuse parent class method, we have two ways

Way: by name, i.e., the parent class name of the parent process ().

class Vehicle: #定义交通工具类
     Country='China'
     def __init__(self,name,speed,load,power):
         self.name=name
         self.speed=speed
         self.load=load
         self.power=power

     def run(self):
         print('开动啦...')

class Subway(Vehicle): #地铁
    def __init__(self,name,speed,load,power,line):
        Vehicle.__init__(self,name,speed,load,power)
        self.line=line

    def run(self):
        print('地铁%s号线欢迎您' %self.line)
        Vehicle.run(self)  # 指名道姓的调用

line13=Subway('中国地铁','180m/s','1000人/箱','电',13)
line13.run()

Second way: super ()

class Vehicle: #定义交通工具类
     Country='China'
     def __init__(self,name,speed,load,power):
         self.name=name
         self.speed=speed
         self.load=load
         self.power=power

     def run(self):
         print('开动啦...')

class Subway(Vehicle): #地铁
    def __init__(self,name,speed,load,power,line):
        #super(Subway,self) 就相当于实例本身 在python3中super()等同于super(Subway,self)
        super().__init__(name,speed,load,power)
        self.line=line

    def run(self):
        print('地铁%s号线欢迎您' %self.line)
        super(Subway,self).run()

class Mobike(Vehicle):#摩拜单车
    pass

line13=Subway('中国地铁','180m/s','1000人/箱','电',13)
line13.run()

The difference between these two methods are: First, the way nothing to do with inheritance, and the way two super () is dependent on the succession, and even if there is no direct inheritance, super will continue to look for the future in accordance with mro.

#A没有继承B,但是A内super会基于C.mro()继续往后找
class A:
    def test(self):
        super().test()
class B:
    def test(self):
        print('from B')
class C(A,B):
    pass

c=C()
c.test() #打印结果:from B


print(C.mro())
#[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]

Guess you like

Origin www.cnblogs.com/Kwan-C/p/11535187.html