類具有繼承關(guān)系,并且子類類型可以向上轉(zhuǎn)型看做父類類型,如果我們從 Person 派生出 Student和Teacher ,并都寫了一個who() 方法:
class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender def who(self): return 'I am a Person, my name is %s' % self.name class Student(Person): def __init__(self, name, gender, score): super(Student, self).__init__(name, gender) self.score = score def who(self): return 'I am a Student, my name is %s' % self.name class Teacher(Person): def __init__(self, name, gender, course): super(Teacher, self).__init__(name, gender) self.course = course def who(self): return 'I am a Teacher, my name is %s' % self.name
接著,我們分別把不同類型的who()函數(shù)結(jié)果打印出來:
p = Person('Tim', 'Male') s = Student('Bob', 'Male', 88) t = Teacher('Alice', 'Female', 'English')
運行結(jié)果:
I am a Person, my name is Tim I am a Student, my name is Bob I am a Teacher, my name is Alice
這種行為稱為多態(tài)。從定義上來講,Student和Teacher都擁有來自父類Person繼承的who()方法,以及自己定義的who()方法。但是在實際調(diào)用的時候,會首先查找自身的定義,如果自身有定義,則優(yōu)先使用自己定義的函數(shù);如果沒有定義,則順著繼承鏈向上找。
class Boss(Person): def __init__(self, name, gender,company): super(Boss, self).__init__(name, gender) self.company = company b = Boss('Bob', 'Male', 'Alibaba') b.who() # ==> I am a Person, my name is Bob
在Boss的定義類,沒有定義who方法,所以會順著繼承鏈向上找到父類的who方法并且調(diào)用。
除了從一個父類繼承外,Python允許從多個父類繼承,稱為多重繼承。多重繼承和單繼承沒有特別大的差異,只是在括號內(nèi)加入多個需要繼承的類的名字即可。
class A(object): def __init__(self, a): print ('init A...') self.a = a class B(A): def __init__(self, a): super(B, self).__init__(a) print ('init B...') class C(A): def __init__(self, a): super(C, self).__init__(a) print ('init C...') class D(B, C): def __init__(self, a): super(D, self).__init__(a) print ('init D...')
多重繼承的繼承鏈就不是一棵樹了,它像這樣:
從上圖可知,A類被繼承了兩次,那么A的__init__()方法,是否會被調(diào)用兩次呢?
?>>> d = D('d') init A... init C... init B... init D...
實踐證明,在多重繼承里,A雖然被繼承了兩次,但是__init__()的方法只調(diào)用一次。
多重繼承的目的是從兩種繼承樹中分別選擇并繼承出子類,以便組合功能使用。
舉個例子,Python的網(wǎng)絡(luò)服務(wù)器有TCPServer、UDPServer、UnixStreamServer、UnixDatagramServer,而服務(wù)器運行模式有 多進程ForkingMixin 和 多線程ThreadingMixin兩種。
要創(chuàng)建多進程模式的 TCPServer:
class MyTCPServer(TCPServer, ForkingMixin) pass
要創(chuàng)建多線程模式的 UDPServer:
class MyUDPServer(UDPServer, ThreadingMixin): pass
如果沒有多重繼承,要實現(xiàn)上述所有可能的組合需要 4x2=8 個子類。
已知類Student、Teacher繼承Person類,技能類BasketballMixin、FootballMixin繼承SkillMixin類,請通過多重繼承,分別定義“會打籃球的學(xué)生”和“會踢足球的老師”。
參考答案:
class Person(object): pass class Student(Person): pass class Teacher(Person): pass class SkillMixin(object): pass class BasketballMixin(SkillMixin): def skill(self): return 'basketball' class FootballMixin(SkillMixin): def skill(self): return 'football' class BStudent(BasketballMixin, Student): pass class FTeacher(FootballMixin, Teacher): pass s = BStudent() print(s.skill()) t = FTeacher() print(t.skill())
請驗證,完成請求
由于請求次數(shù)過多,請先驗證,完成再次請求
打開微信掃碼自動綁定
綁定后可得到
使用 Ctrl+D 可將課程添加到書簽
舉報