🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 单继承 ~~~ # 定义一个父类,如下: class Cat(object): def __init__(self, name, color="白色"): self.name = name self.color = color def run(self): print("%s--在跑"%self.name) # 定义一个子类,继承Cat类如下: class Bosi(Cat): def setNewName(self, newName): self.name = newName def eat(self): print("%s--在吃"%self.name) bs = Bosi("印度猫") print('bs的名字为:%s'%bs.name) print('bs的颜色为:%s'%bs.color) bs.eat() bs.setNewName('波斯') bs.run() ~~~ 运行结果: ![](https://box.kancloud.cn/b2ceecdc0f61cb2bb38d084fef76ef05_346x224.png) 说明: * 虽然子类没有定义`__init__`方法,但是父类有,所以在子类继承父类的时候这个方法就被继承了,所以只要创建Bosi的对象,就默认执行了那个继承过来的`__init__`方法 * 子类在继承的时候,在定义类时,小括号()中为父类的名字 * 父类的属性、方法,会被继承给子类 # 多继承 ~~~ # 定义一个父类 class A: def printA(self): print('----A----') # 定义一个父类 class B: def printB(self): print('----B----') # 定义一个子类,继承自A、B class C(A,B): def printC(self): print('----C----') obj_C = C() obj_C.printA() obj_C.printB() ~~~ 运行结果: ~~~ ----A---- ----B---- ~~~ ## 对象搜索方法时的先后顺序 如果在上面的多继承例子中,如果父类A和父类B中,有一个同名的方法,那么通过子类去调用的时候,调用哪个? ~~~ #coding=utf-8 class base(object): def test(self): print('----base test----') class A(base): def test(self): print('----A test----') # 定义一个父类 class B(base): def test(self): print('----B test----') # 定义一个子类,继承自A、B class C(A,B): pass obj_C = C() obj_C.test() print(C.__mro__) #可以查看C类的对象搜索方法时的先后顺序 ~~~ 输出 ~~~ ----A test---- (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.base'>, <class 'object'>) ~~~ # 多继承的问题 ![](https://box.kancloud.cn/bd4b41bea58641d8ae175b06aa5c46a6_520x558.png) ~~~ class Parent(object): def __init__(self, name): print('parent的init开始被调用') self.name = name print('parent的init结束被调用') class Son1(Parent): def __init__(self, name, age): print('Son1的init开始被调用') self.age = age Parent.__init__(self, name) print('Son1的init结束被调用') class Son2(Parent): def __init__(self, name, age): print('Son2的init开始被调用') self.age = age Parent.__init__(self, name) print('Son2的init结束被调用') class Grandson(Son1, Son2): def __init__(self, name, age, gender): print('Grandson的init开始被调用') Son1.__init__(self, name, age) Son2.__init__(self, name, gender) print('Grandson的init结束被调用') print('---多继承发生的状态---') gs = Grandson('gradson', 12, '男') ~~~ 输出 ~~~ ---多继承发生的状态--- Grandson的init开始被调用 Son1的init开始被调用 parent的init开始被调用 parent的init结束被调用 Son1的init结束被调用 Son2的init开始被调用 parent的init开始被调用 parent的init结束被调用 Son2的init结束被调用 Grandson的init结束被调用 ~~~ 发现多继承调用的父类的构造方法被调用多次 ## 解决 用super ~~~ class Parent(object): # 为了避免报错,用不定长参数 def __init__(self, name, *args, **kwargs): print('parent的init开始被调用') self.name = name print('parent的init结束被调用') class Son1(Parent): # 为了避免报错,用不定长参数 def __init__(self, name, gender, *args, **kwargs): print('Son1的init开始被调用') super().__init__(name, *args, **kwargs) print('Son1的init结束被调用') class Son2(Parent): # 为了避免报错,用不定长参数 def __init__(self, name, gender, *args, **kwargs): print('Son2的init开始被调用') super().__init__(name, *args, **kwargs) print('Son2的init结束被调用') class Grandson(Son1, Son2): def __init__(self, name, age, gender): print('Grandson的init开始被调用') # 如果里面指定,那就按mro从指定的往后面找 # super(Grandson, self).__init__(self, age, gender) super().__init__(self, age, gender) print('Grandson的init结束被调用') print('---多继承发生的状态---') gs = Grandson('gradson', 12, '男') ~~~