继承是面向对象中一个重要的特征,子类可以通过继承来扩展父类的功能,假如我们项目中需要一个鸟人的对象,这个鸟人对象就需要用到鸟人类,此时我们可以定义两个类 Human 类和 Bird 类,然后让鸟人类继承这两个类,我们的鸟人类就具有了 Human 类和 Bird 类的特征,这行为,我们叫做鸟人类多重继承 Human 类和 Bird 类。
多重继承的写法需要在定义子类的括号内分别写上要继承的父类。
class Human(object): def __init__(self): pass class Bird(object): def __init__(self): pass class BirdHuman(Human, Bird): def __init__(self): pass
多重继承的子类拥有所有父类的所有属性和方法,这和普通重继承一样。
class Human(object): humanname = "human" def hh(self): print(self.humanname) class Bird(object): birdname = "bird" def bb(self): print(self.birdname) class BirdHuman(Human, Bird): pass birdman = BirdHuman() birdman.hh() birdman.bb() print(birdman.humanname) print(birdman.birdname)
当我们在父类中通过构造函数定义属性的时候,多重继承和普通继承采用一样的方式(参考上一章继承和多态一节), 也就是说,我们可以通过子类把子类的对象传给父类(一般通过在子类的构造函数中调用父类的构造函数)。
class Human(object): def __init__(self): self.humanname = "human" def hh(self): print(self.humanname) class Bird(object): def __init__(self): self.birdname = "bird" def bb(self): print(self.birdname) class BirdHuman(Human, Bird): def __init__(self): Human.__init__(self) Bird.__init__(self) birdman = BirdHuman() birdman.hh() birdman.bb() print(birdman.humanname) print(birdman.birdname)
如果多重继承的子类的多个父类中有重名的方法,则调用的是第一个继承的父类的方法。
class Human(object): def __init__(self): self.humanname = "I'm a man" def func(self): print(self.humanname) class Bird(object): def __init__(self): self.birdname = "I'm a bird" def func(self): print(self.birdname) class BirdHuman(Human, Bird): # 第一个继承的父类是 Human 类 def __init__(self): Human.__init__(self) Bird.__init__(self) birdman = BirdHuman() birdman.func() # 调用的是 Human 类的 func 函数
如果多重继承的子类的多个父类中有重名的属性,调用的是到目前为止给该属性赋值的类中的属性,这个理所当然。
class Human(object): def __init__(self): self.name = "human" class Bird(object): def __init__(self): self.name = "bird" class BirdHuman(Human, Bird): def __init__(self): Human.__init__(self) Bird.__init__(self) birdman = BirdHuman() print(birdman.name) # 最后一次调用的是 Bird 的构造函数,所以目前为止 name 为 bird class BirdHumanTwo(Human, Bird): def __init__(self): Bird.__init__(self) Human.__init__(self) birdmantwo = BirdHumanTwo() print(birdmantwo.name) # 最后一次调用的是 Human 的构造函数,所以目前为止 name 为 human
如果在我们 BirdHuman 类中,我们认为该类中含有的 Human 的功能比较多, 而 Bird 类中仅仅只是一个辅助类,里面只有很少的属性和方法, 在 Python 中这种多重继承关系,我们把 Bird 这种辅助类叫作 MixIn,我们写代码的时候要习惯于给辅助父类命名的时候加上 MixIn,当然你也可以不加上这个关键字。
class Human(object): def __init__(self): pass class BirdMixIn(object): def __init__(self): pass class BirdHuman(Human, BirdMixIn): def __init__(self): pass
会使用多重继承。
知道什么是MixIn。
我们还有一种设计方案经常来替代多重继承,项目开发中我们常常使用包含的设计方式替代继承,比如对于鸟人类, 我们没必要采用继承的方式,我们可以创建一个鸟人类,在这个鸟人类里面包含有 Bird 类的对象和 Human 类的对象,请大家写出这种方案的实现。
class Bird(object): def __init__(self): self.birdname="bird" class Human(object): def __init__(self): self.humanname="human" class BirdHuman(object): def __init__(self): self.bird=Bird() self.human=Human() def speak(self): print('I am '+self.bird.birdname+" and "+self.human.humanname) birdhuman=BirdHuman() birdhuman.speak()
你在实际开发中有用过多重继承吗? 我个人从来没有任何一次用到过...
‘组合优于继承’
有一些用法,比如说mixin,是将某些通用的实现抽出来作为一个类,然后注入到别的类里面,不过python里都有替代的实现方法
真干货,干了
谢谢 学习了
你好,这边我有个问题,我定义了一个python类,类中属性各自又有各自定义属性,这应该怎么定义?希望解答。
大神,写的真好!