python 繼承和派生
python內建的類檢視: >>> help(__builtins__)
1、繼承 inheritance / 派生 derived
【1】 繼承是指從已有的類中派生出新的類,新類具有原類的行為,並能擴充套件新的行為
【2】 派生類就是從一個已有類中衍生成新類,在新類上可以新增新的屬性和行為
2、作用
【1】用繼承派生機制,可以將一些共有功能加在基類中,實現程式碼的共享
【2】在不改變基類的程式碼的基礎上改變原有的功能
3、
【1】基類(base class) /超類(super class)/ 父類(father class)
【2】派生類(derived class) / 子類(child class)
4、單繼承
【1】單繼承是指由一個基類衍生出新的類
【2】python3 任何類都直接或間接的繼承自object類 object 類是一切類的超類
class 類名(基類名):
pass
# 此示例示意單繼承的用法: class Human: # 人類的共性 def say(self, what): print("say:", what) def walk(self, distance): # 走路 print("走了", distance, '公里') class Student(Human): defstudy(self, subject): print("正在學習:", subject) class Teacher(Student): '''說話,行走,教學''' def teach(self, subject): print("正在教:", subject) h1 = Human() h1.say('天氣晴了') h1.walk(5) print('---------------') s1 = Student() s1.walk(4) s1.say('感覺有點累') s1.study('Python') print('===============') t1 = Teacher() t1.walk(6) t1.say('吃點啥好呢') t1.teach('面向物件') t1.study('轉魔方') class Skill: def fire(self): print("release Fire skill") class Riven: camp='Noxus' def __init__(self,nickname): self.nickname=nickname self.skill5=Skill().fire()#Skill類產生一個物件,並呼叫fire()方法,賦值給例項的skill5屬性 r1=Riven("瑞雯")
5、覆蓋 override
覆蓋是指在有繼承關係的類中,子類中實現了與基類同名的方法,在子類的例項呼叫該方法時,
實際呼叫的是子類中的覆蓋版本,這種現象叫做覆蓋。
In [161]: # 此示例示意B類的works方法覆蓋A類的works方法 ...: class A: ...: def works(self): ...: print("A.works被呼叫") ...: ...: ...: class B(A): ...: ''' B類繼承自A類''' ...: def works(self): ...: print("B.works被呼叫") ...: ...: ...: b = B() ...: b.works() # 呼叫B類的works ...: ...: a = A() ...: a.works() # 呼叫A類的works B.works被呼叫 A.works被呼叫
In [162]: # 此示例示意B類的works方法覆蓋A類的works方法 ...: class A: ...: def works(self): ...: print("A.works被呼叫") ...: ...: ...: class B(A): ...: ''' B類繼承自A類''' ...: def works(self): ...: print("B.works被呼叫") ...: ...: ...: b = B() ...: b.works() # B.works被呼叫 ...: A.works(b) # 用類名顯式呼叫A類的works, A.works被呼叫 ...: B.works被呼叫 A.works被呼叫
6、子類呼叫父類中的重名方法
【1】子類物件顯式呼叫基類(被覆蓋)方法的方式:
基類名.方法名(例項, 實際呼叫傳參)
【2】super().方法名(引數) #只能在方法內使用
【3】super(子類名,子類例項).方法名(引數)
7、super函式
用於在子類中呼叫父類中被覆蓋的方法
super(cls, obj)
cls,子類名。obj,子類的例項
返回繫結超類的例項
super()
返回繫結超類的例項,等同於: super(__class__, 例項方法的第一個引數), 必須在方法內呼叫
【作用】: 藉助super() 返回的基類的例項間接呼叫其父類的覆蓋方法
In [165]: # 此示例示意用super函式返回的物件呼叫父類的覆蓋方法
...: class A:
...: def works(self):
...: print("A.works被呼叫")
...:
...: class B(A):
...: ''' B類繼承自A類'''
...: def works(self):
...: print("B.works被呼叫")
...:
...: def super_work(self):
...: self.works() # B.works被呼叫
...: super(B, self).works() # A.works被呼叫
...: super().works() # A.works被呼叫
...:
...:
...: b = B()
...: b.works() # B.works被呼叫
...: super(B, b).works() # A.works被呼叫
...: b.super_work() # ...
...: # super().works() # 出錯,只能在方法內呼叫
...: A.works(b)
...:
B.works被呼叫
A.works被呼叫
B.works被呼叫
A.works被呼叫
A.works被呼叫
A.works被呼叫
8、繼承中的初始化方法
當子類中實現了 __init__ 方法,
基類的初始化方法並不會被呼叫 def __init__(self, ...)
In [166]: # 此示例示意 用super函式顯示呼叫基類__init__初始化方法 ...: class Human: ...: def __init__(self, n, a): ...: self.name, self.age = n, a ...: print("Human的__init__方法被呼叫") ...: ...: def infos(self): ...: print("姓名:", self.name) ...: print("年齡:", self.age) ...: ...: ...: class Student(Human): ...: def __init__(self, n, a, s=0): ...: super().__init__(n, a) # 顯式呼叫父類的初始化方法 ...: self.score = s # 新增成績屬性 ...: print("Student類的__init__方法被呼叫") ...: ...: def infos(self): ...: super().infos() # 呼叫父類的方法 ...: print("成績:", self.score) ...: ...: ...: s1 = Student('小張', 20, 100) ...: s1.infos() Human的__init__方法被呼叫 Student類的__init__方法被呼叫 姓名: 小張 年齡: 20 成績: 100