新聞中心
Python面向對象編程之繼承與多態(tài)詳解
Python面向對象編程之繼承與多態(tài)詳解
創(chuàng)新互聯(lián)是一家業(yè)務范圍包括IDC托管業(yè)務,雅安服務器托管、主機租用、主機托管,四川、重慶、廣東電信服務器租用,BGP機房服務器托管,成都網(wǎng)通服務器托管,成都服務器租用,業(yè)務范圍遍及中國大陸、港澳臺以及歐美等多個國家及地區(qū)的互聯(lián)網(wǎng)數(shù)據(jù)服務公司。
本文實例講述了Python面向對象編程之繼承與多態(tài)。分享給大家供大家參考,具體如下:
Python 類的繼承
在OOP(Object Oriented Programming)程序設計中,當我們定義一個class的時候,可以從某個現(xiàn)有的class 繼承,新的class稱為子類(Subclass),而被繼承的class稱為基類、父類或超類(Base class、Super class)。
我們先來定義一個class Person,表示人,定義屬性變量 name 及 sex (姓名和性別);
定義一個方法print_title():當sex是male時,print man;當sex 是female時,print woman。參考如下代碼:
class Person(object):
def __init__(self,name,sex):
self.name = name
self.sex = sex
def print_title(self):
if self.sex == "male":
print("man")
elif self.sex == "female":
print("woman")
class Child(Person): # Child 繼承 Person
pass
May = Child("May","female")
Peter = Person("Peter","male")
print(May.name,May.sex,Peter.name,Peter.sex) # 子類繼承父類方法及屬性
May.print_title()
Peter.print_title()
而我們編寫 Child 類,完全可以繼承 Person 類(Child 就是 Person);使用 class subclass_name(baseclass_name) 來表示繼承;
繼承有什么好處?最大的好處是子類獲得了父類的全部屬性及功能。如下 Child 類就可以直接使用父類的 print_title() 方法
實例化Child的時候,子類繼承了父類的構造函數(shù),就需要提供父類Person要求的兩個屬性變量 name 及 sex:
在繼承關系中,如果一個實例的數(shù)據(jù)類型是某個子類,那它也可以被看做是父類(May 既是 Child 又是 Person)。但是,反過來就不行(Peter 僅是 Person,而不是Child)。
繼承還可以一級一級地繼承下來,就好比從爺爺?shù)桨职帧⒃俚絻鹤舆@樣的關系。而任何類,最終都可以追溯到根類object,這些繼承關系看上去就像一顆倒著的樹。比如如下的繼承樹:
isinstance() 及 issubclass()
Python 與其他語言不同點在于,當我們定義一個 class 的時候,我們實際上就定義了一種數(shù)據(jù)類型。我們定義的數(shù)據(jù)類型和Python自帶的數(shù)據(jù)類型,比如str、list、dict沒什么兩樣。
Python 有兩個判斷繼承的函數(shù):isinstance() 用于檢查實例類型;issubclass() 用于檢查類繼承。參見下方示例:
class Person(object):
pass
class Child(Person): # Child 繼承 Person
pass
May = Child()
Peter = Person()
print(isinstance(May,Child)) # True
print(isinstance(May,Person)) # True
print(isinstance(Peter,Child)) # False
print(isinstance(Peter,Person)) # True
print(issubclass(Child,Person)) # True
Python 類的多態(tài)
在說明多態(tài)是什么之前,我們在 Child 類中重寫 print_title() 方法:若為male,print boy;若為female,print girl
class Person(object):
def __init__(self,name,sex):
self.name = name
self.sex = sex
def print_title(self):
if self.sex == "male":
print("man")
elif self.sex == "female":
print("woman")
class Child(Person): # Child 繼承 Person
def print_title(self):
if self.sex == "male":
print("boy")
elif self.sex == "female":
print("girl")
May = Child("May","female")
Peter = Person("Peter","male")
print(May.name,May.sex,Peter.name,Peter.sex)
May.print_title()
Peter.print_title()
當子類和父類都存在相同的 print_title()方法時,子類的 print_title() 覆蓋了父類的 print_title(),在代碼運行時,會調(diào)用子類的 print_title()
這樣,我們就獲得了繼承的另一個好處:多態(tài)。
多態(tài)的好處就是,當我們需要傳入更多的子類,例如新增 Teenagers、Grownups 等時,我們只需要繼承 Person 類型就可以了,而print_title()方法既可以直不重寫(即使用Person的),也可以重寫一個特有的。這就是多態(tài)的意思。調(diào)用方只管調(diào)用,不管細節(jié),而當我們新增一種Person的子類時,只要確保新方法編寫正確,而不用管原來的代碼。這就是著名的“開閉”原則:
對擴展開放(Open for extension):允許子類重寫方法函數(shù)
對修改封閉(Closed for modification):不重寫,直接繼承父類方法函數(shù)
子類重寫構造函數(shù)
子類可以沒有構造函數(shù),表示同父類構造一致;子類也可重寫構造函數(shù);現(xiàn)在,我們需要在子類 Child 中新增兩個屬性變量:mother 和 father,我們可以構造如下(建議子類調(diào)用父類的構造方法,參見后續(xù)代碼):
class Person(object):
def __init__(self,name,sex):
self.name = name
self.sex = sex
class Child(Person): # Child 繼承 Person
def __init__(self,name,sex,mother,father):
self.name = name
self.sex = sex
self.mother = mother
self.father = father
May = Child("May","female","April","June")
print(May.name,May.sex,May.mother,May.father)
若父類構造函數(shù)包含很多屬性,子類僅需新增1、2個,會有不少冗余的代碼,這邊,子類可對父類的構造方法進行調(diào)用,參考如下:
class Person(object):
def __init__(self,name,sex):
self.name = name
self.sex = sex
class Child(Person): # Child 繼承 Person
def __init__(self,name,sex,mother,father):
Person.__init__(self,name,sex) # 子類對父類的構造方法的調(diào)用
self.mother = mother
self.father = father
May = Child("May","female","April","June")
print(May.name,May.sex,May.mother,May.father)
多重繼承
多重繼承的概念應該比較好理解,比如現(xiàn)在需要新建一個類 baby 繼承 Child , 可繼承父類及父類上層類的屬性及方法,優(yōu)先使用層類近的方法,代碼參考如下:
class Person(object):
def __init__(self,name,sex):
self.name = name
self.sex = sex
def print_title(self):
if self.sex == "male":
print("man")
elif self.sex == "female":
print("woman")
class Child(Person):
pass
class Baby(Child):
pass
May = Baby("May","female") # 繼承上上層父類的屬性
print(May.name,May.sex)
May.print_title() # 可使用上上層父類的方法
class Child(Person):
def print_title(self):
if self.sex == "male":
print("boy")
elif self.sex == "female":
print("girl")
class Baby(Child):
pass
May = Baby("May","female")
May.print_title() # 優(yōu)先使用上層類的方法
Python子類繼承,如果不用父類的函數(shù)和方法,應該怎么寫?
子類繼承父類時,如果父類有需要初始化的屬性,那么必須在子類中調(diào)用父類的初始化方法,幫助父類進行初始化,否則,子類可以不調(diào)用父類的初始化方法
代碼示例
"""
父類Car中沒有屬性需要初始化,所有子類中也不需要調(diào)用父類的初始化方法
"""
class?Car:
def?show_name(self):
print('car?name')
class?EeleCar(Car):
pass
car?=?EeleCar()
car.show_name()
Python中繼承的理解與運用?
9.5. 繼承
當然,如果一種語言不支持繼承就,“類”就沒有什么意義。派生類的定義如下所示:
class DerivedClassName(BaseClassName):
命名 BaseClassName (示例中的基類名)必須與派生類定義在一個作用域內(nèi)。除了類,還可以用表達式,基類定義在另一個模塊中時這一點非常有用:
class DerivedClassName(modname.BaseClassName):
派生類定義的執(zhí)行過程和基類是一樣的。構造派生類對象時,就記住了基類。這在解析屬性引用的時候尤其有用:如果在類中找不到請求調(diào)用的屬性,就搜索基類。如果基類是由別的類派生而來,這個規(guī)則會遞歸的應用上去。
派生類的實例化沒有什么特殊之處: DerivedClassName() (示列中的派生類)創(chuàng)建一個新的類實例。方法引用按如下規(guī)則解析:搜索對應的類屬性,必要時沿基類鏈逐級搜索,如果找到了函數(shù)對象這個方法引用就是合法的。
派生類可能會覆蓋其基類的方法。因為方法調(diào)用同一個對象中的其它方法時沒有特權,基類的方法調(diào)用同一個基類的方法時,可能實際上最終調(diào)用了派生類中的覆蓋方法。(對于 C++ 程序員來說,Python 中的所有方法本質(zhì)上都是 虛 方法。)
派生類中的覆蓋方法可能是想要擴充而不是簡單的替代基類中的重名方法。有一個簡單的方法可以直接調(diào)用基類方法,只要調(diào)用: BaseClassName.methodname(self, arguments)。有時這對于客戶也很有用。(要注意只有 BaseClassName 在同一全局作用域定義或導入時才能這樣用。)
Python 有兩個用于繼承的函數(shù):
函數(shù) isinstance() 用于檢查實例類型: isinstance(obj, int) 只有在 obj.__class__ 是 int 或其它從 int 繼承的類型
函數(shù) issubclass() 用于檢查類繼承: issubclass(bool, int) 為 True,因為 bool 是 int 的子類。
然而, issubclass(float, int) 為 False,因為 float 不是 int 的子類。
Python類的繼承與多態(tài)詳細介紹
類(Class): 用來描述具有相同的屬性和方法的對象的集合。
類變量:類變量在整個實例化的對象中是公用的。類變量定義在類中且在函數(shù)體之外。類變量通常不作為實例變量使用。
類有一個名為 __init__() 的特殊方法(構造方法),該方法在類實例化時會自動調(diào)用
self:self 代表的是類的實例,代表當前對象的地址,而 self.class 則指向類。
類調(diào)用 Car.weight
實例化 car01=Car(5)
實例對象調(diào)用 car01.weght
我們在構造類時,Python3默認我們繼承了object這個基類,我個人理解object就是個空的類,可以不用管為何要在括號中寫上object,這是Python3的特性,在python2中如果你沒有寫object的話不會默認繼承了object這個基類。
同樣的我們自己希望繼承的父類只需要把objetc改為我們自己定義的類名即可。子類中可以擁有父類中所有的公有屬性和方法,但是可以通過在變量名前加下劃線使其變?yōu)樗接校@樣子類就不可以訪問父類中的成員了。
以下三個公交車類的父類均為客車類,我們可以寫一個funcs方法使得每次調(diào)用funcs方法時,傳入不同的對象以執(zhí)行不同的func方法,具體實現(xiàn)如下:
主函數(shù) :
可以看到,我將小 汽車 實例化為帶有重量為5t的一個具體對象,將客車實例化為帶有重量為20t的一個具體對象,將三個公交車實例化為帶有重量為15t的一個具體對象.
如上圖所示,我每次在調(diào)用funcs方法時都傳入了一個實例化對象,funcs根據(jù)不同的對象執(zhí)行相應的內(nèi)部方法。
網(wǎng)站題目:函數(shù)繼承python 函數(shù)繼承Python
網(wǎng)頁URL:http://www.ef60e0e.cn/article/doggoed.html