python面向对象 : 继承

一. 初识继承

  继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类.

  当我们在定义多个类的时候,发现要用到相同的方法或变量,如果每个类都要写相同的方法和变量,那么代码就会重复,为了减少代码,可以用继承来解决.

# 三个类中都有相同的参数,造成代码重复

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

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

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

  用继承的思想来做

class Animal:
    animal = '动物'
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age

    def hobby(self):
        print('%s喜欢吃' % self.name)

class Person(Animal):  #继承Animal类
    pass
class Cat(Animal):
    pass
class Dog(Animal):
    pass

print(Person.animal)  #动物  类名可以访问父类所有内容
p = Person('jack', '', 25)
p.hobby()  #jack喜欢吃
# 子类以及子类实例化的对象 可以访问父类的任何方法或变量.先从本类中找hobby方法,找不到则从父类里找
既要执行子类的方法,又要执行父类的方法? 有两种解决方法.
1,Animal.__init__(self, name, sex, age)
2,super().__init__(name,sex,age)
class Animal:
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age

    def eat(self):
        print('%s会吃' % self.name)

    def drink(self):
        print('%s会喝' % self.name)


class Bird(Animal):
    def __init__(self, name, sex, age, wing):
        # super().__init__(name, sex, age )  #自动把self传给父类
        Animal.__init__(self, name, sex, age)
        self.wing = wing

    def egg(self):
        print('鸡会下蛋')

    def eat(self):  #本类含有和弗雷相同的方法名
        super().drink()  #用super()调用父类的方法
        print('鸟会吃虫子')


b = Bird('', '', 30, '翅膀')
print(b.__dict__)  # {'name': '鸟', 'sex': '公', 'age': 30, 'wing': '翅膀'}
b.eat()  
# 鸟会喝    #执行父类的eat方法
# 鸟会吃虫子   #执行本类的eat方法

二. 继承的进

1. 单继承和多继承

class A:
    pass
class B(A):  #单继承
    pass
class C(A):
    pass
class D(B,C):  #多继承
    pass

2. 经典类, 新式类 

  新式类: 凡是继承object类都是新式类. python3x 所有的类都是新式类,因为python3x中的类都默认继承object.

  经典类: 不继承object类都是经典类, python2x:(既有新式类,又有经典类) 所有的类默认都不继承object类,所有的类默认都是经典类.你可以让其继承      object.

   单继承: 新式类,经典类查询顺序一样.
   多继承继承顺序(讨论的是继承两个类):
新式类: 遵循广度优先 : 一条路走到倒数第二级,判断,如果其他路能走到终点,则返回走另一条路.如果不能,则走到终点. 可以用mro()来查询继承顺序.
       经典类: 遵循深度优先 : 一条路走到底.
class A:
    def func(self):
        print('IN A')

class B(A):
    # pass
    def func(self):
        print('IN B')

class C(A):
    # pass
    def func(self):
        print('IN C')

class D(B):
    # pass
    def func(self):
        print('IN D')

class E(C):
    def func(self):
        print('IN E')

class F(D,E):
    # pass
    def func(self):
        print('IN F')

f1 = F()
f1.func()  #IN F

print(F.mro())  # 查询类的继承顺序
# [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, 
# <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

 3. 多继承原理: MRO_C算法

 mro():  查询类的继承顺序.  代码和步骤如下:
class H:
    pass


class G(H):
    pass


class F(H):
    pass


class E(G):
    pass


class D(F):
    pass


class C(E):
    pass


class B(D):
    pass


class A(B, C, D):
    pass


print(A.mro())

'''
首先找到A继承的三个类的深度继承顺序,放到一个列表中

B   [B,D,F,H]
C   [C,E,G,H]
D   [D,F,H]

每个列表的第一个元素为头部,其它位置元素都为尾部,从第一个列表的头部开始找,找其他列表中尾部是否含有
这个类名,如果没有,提取出来放到一个列表中,如果有,找下一个列表的头部,循环下去
只要提取来一个,我们就从第一个列表的头部接着重复上面的操作.

A   [A][B,D,F,H] [C,E,G,H] [D,F,H] [B,C,D]  A #找到第一个列表的头A,其他列表尾部没有A,把A取出来,如果其他列表的头部有A则剔除
    [][B,D,F,H] [C,E,G,H] [D,F,H] [B,C,D]   B
    [][D,F,H] [C,E,G,H] [D,F,H] [C,D]       C
    [][D,F,H] [E,G,H] [D,F,H] [D]           D
    [][F,H] [E,G,H] [F,H] []                F 
    [][H] [E,G,H] [H] []                    E #找到第一个列表的头部H,但是其他列表尾部有H,所以跳过这个列表,去下一个列表取头部
    [][H] [G,H] [H] []                      G
    [][H] [H] [H] []                        H
    [][] [] [] [] 
    lst = [A,B,C,D,F,E,G,H] 
'''

class F:
    pass


class E:
    pass


class D:
    pass


class C(D, F):
    pass


class B(E, D):
    pass


class A(B, C):
    pass


print(A.mro())
'''
首先找到A继承的两个类的深度继承顺序
把B作为子类,找出B类的查询顺序

B   [B] [E] [D] [E,D]  B  
    [] [E] [D] [E,D]   E
    [] [] [D] [D]      D
    [] [] [] []
    lst = [B,E,D]
把C作为子类,找出C类的查询顺序

C   [C] [D] [F] [D,F]  C
    [] [D] [F] [D,F]   D
    [] [] [F] [F]      F
    [] [] [] []       
    lst = [C,D,F]

A   [A] [B,E,D] [C,D,F] [B,C]  A
    [] [B,E,D] [C,D,F] [B,C]   B 
    [] [E,D] [C,D,F] [C]       E
    [] [D] [C,D,F] [C]         C
    [] [D] [D,F] []            D
    [] [] [F] []               F
    [] [] [] []
    lSt = [A,B,E,C,D,F]    
'''





 


 
无限的我,现在才开始绽放,从东边的第一缕阳光到西边的尽头
原文地址:https://www.cnblogs.com/huangqihui/p/9367520.html