在OOP(Object Oriented PRogramming)程序設計中,當我們定義一個class的時候,可以從某個現有的class 繼承,新的class稱為子類(Subclass),而被繼承的class稱為基類、父類或超類(Base class、Super class)。
我們先來定義一個class Person,表示人,定義屬性變量 name 及 sex (姓名和性別);
定義一個方法print_title():當sex是male時,print man;當sex 是female時,print woman。參考如下代碼:
1 class Person(object): 2 def __init__(self,name,sex): 3 self.name = name 4 self.sex = sex 5 6 def print_title(self): 7 if self.sex == "male": 8 print("man") 9 elif self.sex == "female":10 print("woman")11 12 class Child(Person): # Child 繼承 Person13 pass14 15 May = Child("May","female")16 Peter = Person("Peter","male")17 18 print(May.name,May.sex,Peter.name,Peter.sex) # 子類繼承父類方法及屬性19 May.print_title()20 Peter.print_title()
而我們編寫 Child 類,完全可以繼承 Person 類(Child 就是 Person);使用 class subclass_name(baseclass_name) 來表示繼承;
繼承有什么好處?最大的好處是子類獲得了父類的全部屬性及功能。如下 Child 類就可以直接使用父類的 print_title() 方法
實例化Child的時候,子類繼承了父類的構造函數,就需要提供父類Person要求的兩個屬性變量 name 及 sex:
在繼承關系中,如果一個實例的數據類型是某個子類,那它也可以被看做是父類(May 既是 Child 又是 Person)。但是,反過來就不行(Peter 僅是 Person,而不是Child)。
繼承還可以一級一級地繼承下來,就好比從爺爺到爸爸、再到兒子這樣的關系。而任何類,最終都可以追溯到根類object,這些繼承關系看上去就像一顆倒著的樹。比如如下的繼承樹:
Python%20與其他語言不同點在于,當我們定義一個%20class%20的時候,我們實際上就定義了一種數據類型。我們定義的數據類型和Python自帶的數據類型,比如str、list、dict沒什么兩樣。
Python%20有兩個判斷繼承的函數:isinstance()%20用于檢查實例類型;issubclass()%20用于檢查類繼承。參見下方示例:
class%20Person(object):%20%20%20%20passclass%20Child(Person):%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20#%20Child%20繼承%20Person%20%20%20%20passMay%20=%20Child()Peter%20=%20Person()%20%20%20%20print(isinstance(May,Child))%20%20%20%20%20%20%20%20%20#%20Trueprint(isinstance(May,Person))%20%20%20%20%20%20%20%20#%20Trueprint(isinstance(Peter,Child))%20%20%20%20%20%20%20#%20Falseprint(isinstance(Peter,Person))%20%20%20%20%20%20#%20Trueprint(issubclass(Child,Person))%20%20%20%20%20%20#%20True
在說明多態是什么之前,我們在%20Child%20類中重寫%20print_title()%20方法:若為male,print boy;若為female,print girl
%201%20class%20Person(object):%202%20%20%20%20%20def%20__init__(self,name,sex):%203%20%20%20%20%20%20%20%20%20self.name%20=%20name%204%20%20%20%20%20%20%20%20%20self.sex%20=%20sex%205%20%20%20%20%20%20%20%20%20%206%20%20%20%20%20def%20print_title(self):%207%20%20%20%20%20%20%20%20%20if%20self.sex%20==%20"male":%208%20%20%20%20%20%20%20%20%20%20%20%20%20print("man")%209%20%20%20%20%20%20%20%20%20elif%20self.sex%20==%20"female":10%20%20%20%20%20%20%20%20%20%20%20%20%20print("woman")11%2012%20class%20Child(Person):%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20#%20Child%20繼承%20Person13%20%20%20%20%20def%20print_title(self):14%20%20%20%20%20%20%20%20%20if%20self.sex%20==%20"male":15%20%20%20%20%20%20%20%20%20%20%20%20%20print("boy")16%20%20%20%20%20%20%20%20%20elif%20self.sex%20==%20"female":17%20%20%20%20%20%20%20%20%20%20%20%20%20print("girl")18%20%20%20%20%20%20%20%20%2019%20May%20=%20Child("May","female")20%20Peter%20=%20Person("Peter","male")21%2022%20print(May.name,May.sex,Peter.name,Peter.sex)23%20May.print_title()24%20Peter.print_title()
當子類和父類都存在相同的%20print_title()方法時,子類的%20print_title()%20覆蓋了父類的%20print_title(),在代碼運行時,會調用子類的%20print_title()
這樣,我們就獲得了繼承的另一個好處:多態。
多態的好處就是,當我們需要傳入更多的子類,例如新增%20Teenagers、Grownups%20等時,我們只需要繼承%20Person%20類型就可以了,而print_title()方法既可以直不重寫(即使用Person的),也可以重寫一個特有的。這就是多態的意思。調用方只管調用,不管細節,而當我們新增一種Person的子類時,只要確保新方法編寫正確,而不用管原來的代碼。這就是著名的“開閉”原則:
子類可以沒有構造函數,表示同父類構造一致;子類也可重寫構造函數;現在,我們需要在子類%20Child%20中新增兩個屬性變量:mother%20和%20father,我們可以構造如下(建議子類調用父類的構造方法,參見后續代碼):
1 class Person(object): 2 def __init__(self,name,sex): 3 self.name = name 4 self.sex = sex 5 6 class Child(Person): # Child 繼承 Person 7 def __init__(self,name,sex,mother,father): 8 self.name = name 9 self.sex = sex10 self.mother = mother11 self.father = father12 13 May = Child("May","female","April","June")14 print(May.name,May.sex,May.mother,May.father)
若父類構造函數包含很多屬性,子類僅需新增1、2個,會有不少冗余的代碼,這邊,子類可對父類的構造方法進行調用,參考如下:
1 class Person(object): 2 def __init__(self,name,sex): 3 self.name = name 4 self.sex = sex 5 6 class Child(Person): # Child 繼承 Person 7 def __init__(self,name,sex,mother,father): 8 Person.__init__(self,name,sex) # 子類對父類的構造方法的調用 9 self.mother = mother10 self.father = father11 12 May = Child("May","female","April","June")13 print(May.name,May.sex,May.mother,May.father)
多重繼承的概念應該比較好理解,比如現在需要新建一個類 baby 繼承 Child , 可繼承父類及父類上層類的屬性及方法,優先使用層類近的方法,代碼參考如下:
1 class Person(object): 2 def __init__(self,name,sex): 3 self.name = name 4 self.sex = sex 5 6 def print_title(self): 7 if self.sex == "male": 8 print("man") 9 elif self.sex == "female":10 print("woman")11 12 class Child(Person):13 pass14 15 class Baby(Child):16 pass17 18 May = Baby("May","female") # 繼承上上層父類的屬性19 print(May.name,May.sex) 20 May.print_title() # 可使用上上層父類的方法21 22 23 class Child(Person): 24 def print_title(self):25 if self.sex == "male":26 print("boy")27 elif self.sex == "female":28 print("girl")29 30 class Baby(Child):31 pass32 33 May = Baby("May","female")34 May.print_title() # 優先使用上層類的方法
新聞熱點
疑難解答