- 繼承
面向對象編程語言的一個主要功能就是“繼承”。
繼承是指這樣一種能力:它可以使用現有類的所有功能,並在無需重新編寫原來的類的情況下對這些功能進行擴展。
(1) 單繼承:python同時支持類的繼承。如果一種語言不支持繼承,類就沒什么意義。
類還允許派生,即用戶可以創建一個子類,它也是類,而且繼承父類(即基類)的所有特征和屬性。
創建派生類的語法格式為:
class DerivedClassName(BaseClassName):
<statement-1>
...
<statement-N>
基類名BaseClassName必須與派生類定義在一個作用域內。除了用類名,還可以用表達式。
例如:單繼承舉例:
class people:
#定義基本屬性
name=''
age=0
#定義私有屬性,私有屬性在類外部無法直接進行訪問
__weight=0
#定義構造方法
def __init__(self,n,a,w):
self.name=n
self.age=a
self.__weight=w
def speak(self):
print("%s says:I am %d years old"%(self.name,self.age))
#單繼承
class student(people):
grade=''
#調用父類的構造函數
def __init__(self,n,a,w,g):
people.__init__(self,n,a,w) #student繼承並使用people的__init__函數
self.grade=g #不同於people的參數g
#重寫父類的方法
def speak(self):
#顯示student的信息
print("%s says:I am %d years old,I am in Grade %d."%(self.name,self.age,self.grade))
s=student('Tom',10,90,3) #實例化student類
s.speak() #顯示student的speak方法
#運行結果:Tom says:I am 10 years old,I am in Grade 3.
(2) 多繼承:某個類繼承了多個父類
多繼承的類定義語法格式如下:
class DerivedClassName(Base1,Base2,Base3):
<statement-1>
...
<statament-N>
#注意解析類屬性的規則是,順序是深度優先,從左到右。因此,如果在DerivedClassName(示例中的派生類)中沒有找到這個屬性,就會搜索Base1,然后遞歸的搜索其基類,如果最終沒有找到,就搜索Base2,依次類推。深度優先不區分屬性繼承自基類還是直接定義。
例如:class people:
#定義基本屬性
name=''
age=0
__weight=0
#定義構造方法
def __init__(self,n,a,w):
self.name=n
self.age=a
self.__weight=w
def speak(self):
print("%s says:I am %d years old"%(self.name,self.age))
#單繼承
class student(people):
grade=''
#調用父類的構造函數
def __init__(self,n,a,w,g):
people.__init__(self,n,a,w) #student繼承並使用people的__init__函數
self.grade=g
def speak(self):
print("%s says:I am %d years old,I am in Grade %d."%(self.name,self.age,self.grade))
class speaker():
topic=''
name=''
def __init__(self,n,t):
self.name=n
self.topic=t
def speak(self):
print("I am %s,I am a speaker,my topic is %s"%(self.name,self.topic))
class sample(speaker,student):
a=''
def __init__(self,n,a,w,g,t):
student.__init__(self,n,a,w,g)
speaker.__init__(self,n,t)
test_1=sample("Tom",12,90,3,"One World One Dream")
test_1.speak()
#執行結果:I am Tom,I am a speaker,my topic is one World One Dream.
(3) 補充:
1.方法重寫
如果父類方法的功能不能滿足需求,可以在子類里重寫父類的方法。
例如:
class Parent: #定義父類
def myMethod(self):
print('調用父類方法')
class Child(Parent): #定義子類
def myMethod(self):
print('調用子類方法')
Child_1=Child() #子類實例
Child_1.myMethod() #子類調用重寫方法
輸出:調用子類方法
2. if__name__=’__main__’的作用
這條語句的意思是,讓程序員寫的腳本模塊既可以導入到別的模塊中調用,也可以在模塊中自己執行。
例如 #y1htext.py
def main():
print('hello world,I am in %s now.' %__name__)
if __name__=='__main__':
main() 運行結果:hello world,I am in __main__now.
在這個文件中定義了一個main()函數,如果執行該.py文件,則if語句中的內容被執行,成功調用main()函數。
從另一個模塊導入該模塊,這個模塊的名字是test1.py
#test1.py
from y1htext import main
mian() #相同的運行結果
3. 運算符重載:用於新類的運算符的實現。
運算符重載是針對新類型數據的實際需要,對原有運算符進行適當的改造,一般來說,重載的功能應當與原有功能相類似,不能改變原運算符的操作對象個數,同時至少要有一個操作對象是自定義類型。
Python支持運算符重載,它的運算符重載就是通過重寫這些python內建方法來實現的。這些內建方法都是以雙下划線開頭和結尾的,Python通過這種特殊的命名方式來攔截操作符,以實現重載。
例如:+用__add__方法,+=用__iadd__方法,...,*用__mul__方法等
當Python的內置操作運用於類對象時,Python會去搜索並調用對象中指定的方法來完成操作。運算符重載是通過創建運算符函數實現的,運算符重載實際是一個函數,所以運算符的重載實際上是函數的重載。
例如:運算符重載
class Computation():
def __init__(self,value):
self.value=value
def __add__(self,other):
return(self.value+other.value)
def __sub__(self,other):
return(self.value-other.value)
c1=Computation(10)
c2=Computation(10)
print(c1+c2)
print(c1-c2) #“-”在作用於類對象,實現減法運算符的重載
說明:如果類實現了__add__的方法,當類的對象出現在“+”運算符中時,會調用這個方法;如果類實現了__sub__方法,當類的對象出現在“-”運算符中時,會調用這個方法。重載這兩個方法就是可以在普通的類對象上添加“+”和“-”運算。
(4) isinstance函數(Python語言的一個內建函數)
語法:isinstance(object,type) 函數是Python語言的一個內建函數
作用是:判斷一個對象或者變量是否是一個已知的類型。
① 針對類來說,如果參數是object是type類的實例(判斷一個對象是否為該類的實例)或者object是type類的子類的一個實例,則返回True.如果object不是一個給定類型的對象,則返回結果是False.
class objA:
pass
class objB(objA):
pass
A=objA()
B=objB()
print(isinstance(A,objA))
print(isinstance(B,objA))
print(isinstance(A,objB))
print(isinstance(B,objB))
② 針對變量來說,第一個參數(object)為變量,第二個參數(type)為類型名或者由變量名組成的一個元組(如(int,list,float)),其返回值為布爾型(Ture或False).若第一個參數為一個元組,則變量類型與元組類型名之一相同時即返回True.
a=2
print(isinstance(a,int))
print(isinstance(a,str))
print(isinstance(a,(str,int,list)))
(5) super()函數
當存在繼承關系的時候,有時候需要在子類中調用父類的方法。如果修改父類名稱,那么在子類中會涉及多處修改。
Python引入了super()機制,語法格式如下:
super(type[,object-or-type])
例如:
class A(object):
def __init__(self):
print('enter A')
print('leave A')
class BA.: #B繼承A
def __init__(self):
print("enter B")
super(B,self).__init__() #python2對其理解為:super(B,self)首先找到B的父類(就是類A),然后把類B的對象self轉換為類A的對象,然后被轉換的類A對象調用自己的__init__函數。Python3.x可以不加參數而直接寫為super().__init__,並且可以像父類中的屬性賦值。
print("leave B")
b=B()