前面的兩篇講了面向對象的第一個特性:封裝
今天來講講面向對象的第二個特性:繼承
繼承分爲單繼承以及多繼承
先給出一個例子,看看繼承與非繼承的區別:
這是沒有使用繼承的程序:
#不使用繼承
class Animal :
def eat(self):
print('喫')
def drink(self):
print('喝')
def run(self):
print('跑')
def sleep(self):
print('睡')
class Dog :
def eat(self):
print('喫')
def drink(self):
print('喝')
def run(self):
print('跑')
def sleep(self):
print('睡')
def bark(self):
print('叫')
class Xiaotianquan :
def eat(self):
print('喫')
def drink(self):
print('喝')
def run(self):
print('跑')
def sleep(self):
print('睡')
def bark(self):
print('叫')
def fly(self):
print('飛')
animal = Animal()
dog = Dog()
xiaotianquan = Xiaotianquan()
print('這是Animal類')
animal.eat()
animal.drink()
animal.run()
animal.sleep()
print('')
print('這是Dog類')
dog.eat()
dog.drink()
dog.run()
dog.sleep()
dog.bark()
print('')
print('這是xiaotianquan類')
xiaotianquan.eat()
xiaotianquan.drink()
xiaotianquan.run()
xiaotianquan.sleep()
xiaotianquan.bark()
xiaotianquan.fly()
代碼很長很麻煩也不利於閱讀,這段代碼的結果是:
這是Animal類
喫
喝
跑
睡
這是Dog類
喫
喝
跑
睡
叫
這是xiaotianquan類
喫
喝
跑
睡
叫
飛
接下來這是使用了繼承的代碼:
#使用繼承
class Animal :
def eat(self):
print('喫')
def drink(self):
print('喝')
def run(self):
print('跑')
def sleep(self):
print('睡')
class Dog(Animal) :
def bark(self):
print('叫')
class Xiaotianquan(Dog) :
def fly(self):
print('飛')
animal = Animal()
dog = Dog()
xiaotianquan = Xiaotianquan()
print('這是Animal類')
animal.eat()
animal.drink()
animal.run()
animal.sleep()
print('')
print('這是Dog類')
dog.eat()
dog.drink()
dog.run()
dog.sleep()
dog.bark()
print('')
print('這是xiaotianquan類')
xiaotianquan.eat()
xiaotianquan.drink()
xiaotianquan.run()
xiaotianquan.sleep()
xiaotianquan.bark()
xiaotianquan.fly()
類的代碼簡易了很多,這段代碼的結果是:
這是Animal類
喫
喝
跑
睡
這是Dog類
喫
喝
跑
睡
叫
這是xiaotianquan類
喫
喝
跑
睡
叫
飛
可以看到使用繼承和不使用繼承的結果一樣,但是使用了繼承,代碼的可讀性變強,也變得更短了
使用繼承的時候,根據pycharm給出的智能提示,我們可以看到方法繼承於哪裏
比如我在調用dog的方法時出現了
在調用xiaotianquan的方法時出現了
我們再來看看多繼承
代碼爲:
#多繼承
#假設獅子和老虎的子嗣會繼承老虎頭上的“王”字,也會繼承獅子的爆炸頭
class Tiger :
def wang(self):
print('老虎的頭上有“王”')
class Lion :
def baozhatou(self):
print('獅子有爆炸頭')
class Tiger_Lion(Tiger, Lion) :
pass
baby = Tiger_Lion()
baby.wang()
baby.baozhatou()
結果爲
老虎的頭上有“王”
獅子有爆炸頭
但是如果不同的父類之間存在同名的方法或者屬性,就應該儘量避免使用多繼承
來看個例子
代碼:
#多繼承
#更改括號內父類的順序,繼承的順序也會發生改變
class Tiger :
def feature(self):
print('老虎頭上有“王”')
def bark(self):
print('老虎是森林之王')
class Lion :
def feature(self):
print('獅子有爆炸頭')
def bark(self):
print('獅子是森林之王')
#class Tiger_Lion(Tiger, Lion) :
# pass
class Tiger_Lion(Lion, Tiger) :
pass
baby = Tiger_Lion()
baby.feature()
baby.bark()
結果爲
獅子有爆炸頭
獅子是森林之王
但是如果更改括號內父類的順序
#多繼承
#更改括號內父類的順序,繼承的順序也會發生改變
class Tiger :
def feature(self):
print('老虎頭上有“王”')
def bark(self):
print('老虎是森林之王')
class Lion :
def feature(self):
print('獅子有爆炸頭')
def bark(self):
print('獅子是森林之王')
class Tiger_Lion(Tiger, Lion) :
pass
#class Tiger_Lion(Lion, Tiger) :
# pass
baby = Tiger_Lion()
baby.feature()
baby.bark()
那麼結果就爲
老虎頭上有“王”
老虎是森林之王