您好,登錄后才能下訂單哦!
小編給大家分享一下python中的繼承是什么意思,相信大部分人都還不怎么了解,因此分享這篇文章給大家學習,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去學習方法吧!
面向?qū)ο笳Z言的一個特性就是類的繼承。繼承的關(guān)系跟人類繁衍的關(guān)系相似,被繼承的類稱為基類(也叫做父類),繼承而得的類叫派生類(也叫子類),這種關(guān)系就像人類的父子關(guān)系。
類的繼承,說明了不同類直接的關(guān)系,派生類復(fù)用了基類的代碼同時也繼承了基類的屬性和方法。派生類定義的語法如下:
派生類的定義
class DerivedClassName(BaseClassName): 語句1 ... 語句n
下面我們根據(jù)這個語法來寫一個繼承的例子:
class Person: def __init__(self, name, age, height): self.name = name self.age = age self.height = height def look(self): print(self.name, 'is looking') def walk(self): print(self.name, 'is walking') class Teacher(Person): def __init__(self, name, age, height): super().__init__(name, age, height) def teach(self): print(self.name, 'is teaching') class Student(Person): def __init__(self, name, age, height): super().__init__(name, age, height) def learn(self): print(self.name, 'is learning') if __name__ == '__main__': teacher = Teacher('Tom', 31, 178) s1 = Student('Jim', 12, 160) s2 = Student('Kim', 13, 162) teacher.look() teacher.walk() teacher.teach() print('==='*5) s1.look() s1.walk() s1.learn() print('==='*5) s2.look() s2.walk() s2.learn()
我們定義了一個基類Person,這個人有名字(name)、年齡(age)和身高(height)三個屬性,還有l(wèi)ook(), walk()兩個方法。由它派生出兩個類:Teacher和Student,這兩個派生類繼承了name, age, height屬性,也繼承了look(), walk()方法。但它們又有自己獨有的方法,Teacher可以teach(),Student可以learn()。
運行這個示例代碼,可以得到下面的信息:
Tom is looking Tom is walking Tom is teaching =============== Jim is looking Jim is walking Jim is learning =============== Kim is looking Kim is walking Kim is learning
派生類定義的執(zhí)行過程與基類相同。 當構(gòu)造類對象時,基類會被記住。 此信息將被用來解析屬性引用:如果請求的屬性在類中找不到,搜索將轉(zhuǎn)往基類中進行查找。 如果基類本身也派生自其他某個類,則此規(guī)則將被遞歸地應(yīng)用。
派生類的實例化會創(chuàng)建該類的一個新實例。方法引用將按以下方式解析:搜索相應(yīng)的類屬性,如果搜索的方法在派生類中找不到,就去基類中進行查找,如果基類本身也派生自其它類,則此規(guī)則將被遞歸地應(yīng)用。如果搜索到了一個函數(shù)對象則方法引用就生效。
比如,Teacher中并沒有定義look(),當我們調(diào)用方法teacher.look()的時候會在它的基類Person中找到并調(diào)用look()。
重載基類方法
派生類可以重載基類的方法。重載,就是重新定義。如果派生類中重新定義了基類的某方法,那么派生類的重載的這個方法就會覆蓋基類中的同名方法。
例如,我們定義Student時可以重載walk()方法,讓它擁有Student特征:
class Student(Person): def __init__(self, name, age, height): super().__init__(name, age, height) def learn(self): print(self.name, 'is learning') def walk(self): print('Student:', self.name, 'is walking')
再次運行s1.walk()時,就會打印下面的信息:
Student: Jim is walking
Python有兩個內(nèi)置函數(shù)可被用于檢查繼承機制:
isinstance()來檢查一個實例的類型:isinstance(obj, int)僅僅會在obj.__class__為int或某個派生自int的類時為True。issubclass()來檢查類的繼承關(guān)系:issubclass(bool, int)為True,因為bool是int的子類。但是,issubclass(float, int)為False,因為float不是int的子類。
多重繼承
多重繼承的意思就是,一個派生類同時派生自多個基類,繼承它們?nèi)繉傩院头椒āK亩x形式是:
class DerivedClassName(Base1, Base2, Base3): 語句1 ... 語句1
對于多數(shù)應(yīng)用來說,在最簡單的情況下,你可以認為搜索從父類所繼承屬性的操作是深度優(yōu)先、從左至右的,當層次結(jié)構(gòu)中存在重疊時不會在同一個類中搜索兩次。 因此,如果某一屬性在 DerivedClassName 中未找到,則會到 Base1 中搜索它,然后(遞歸地)到 Base1 的基類中搜索,如果在那里未找到,再到 Base2 中搜索,依此類推。
真實情況比這個更復(fù)雜一些;方法解析順序會動態(tài)改變以支持對 super() 的協(xié)同調(diào)用。 這種方式在某些其他多重繼承型語言中被稱為后續(xù)方法調(diào)用,它比單繼承型語言中的 super 調(diào)用更強大。
比如,我們要定義一個“助教”類,助教是幫助老師教學的高年級同學。他兼具老師和學生的特點,我們可以讓這個類多重繼承“老師類”和“學生類”。
私有變量
我們上一節(jié)講過,Python中沒有類似C++中的“私有變量”。但是,大多數(shù)Python代碼都遵循這樣一個約定(只是約定但很重要):帶有一個下劃線的名稱(例如:_name)應(yīng)當被動作是API的非僅供部分(無論它是函數(shù)、方法或是數(shù)據(jù)成員)。 這應(yīng)當被視為一個實現(xiàn)細節(jié),可能不經(jīng)通知即加以改變。
由于存在對于類私有成員的有效使用場景(例如避免名稱與子類所定義的名稱相沖突),因此存在對此種機制的有限支持,稱為名稱改寫。 任何形式為__name的標識符(至少帶有兩個前綴下劃線,至多一個后綴下劃線)的文本將被替換為_classname__name,其中classname為去除了前綴下劃線的當前類名稱。這種改寫不考慮標識符的句法位置,只要它出現(xiàn)在類定義內(nèi)部就會進行。
名稱改寫有助于讓子類重載方法而不破壞類內(nèi)方法調(diào)用。例如:
class MyList: def __init__(self, iterable): self.items_list = [] self.__update(iterable) def update(self, iterable): for item in iterable: self.items_list.append(item) __update = update # 把update()拷貝給私有方法 class MyListSubclass(MyList): def update(self, keys, values): # 重載 update() # 但不會破壞 __init__() for item in zip(keys, values): self.items_list.append(item)
這個示例中即使正在MyListSubclass引入一個__update標識符的情況下也不會出錯,因為它會在MyList類中被替換為_MyList__update,而在MyListSubclass類中被替換為_MyListSubclass__update。
改寫規(guī)則的設(shè)計主要是為了避免意外沖突;訪問或修改被視為私有的變量仍然是可能的。這在特殊情況下甚至會很有用,例如在調(diào)試器中。
請注意傳遞給 exec() 或 eval() 的代碼不會將發(fā)起調(diào)用類的類名視作當前類;這類似于 global 語句的效果,因此這種效果僅限于同時經(jīng)過字節(jié)碼編譯的代碼。 同樣的限制也適用于 getattr(), setattr() 和 delattr(),以及對于 dict 的直接引用。
類的繼承體現(xiàn)了類的關(guān)系,基類的屬性和方法可以被派生類繼承,同時派生類又可以重載基類的方法。派生類既可以單獨繼承一個基類,也可以多重繼承多個基類。Python的類沒有真正意義上的私有變量,通過約定和名稱改寫來有限支持私有變量。
以上是python中的繼承是什么意思的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。