(一)Python入門-6面向對象編程:07面向對象三大特征(封裝、繼承、多態)-繼承
一:面向對象三大特征介紹
Python是面向對象的語言,也支持面向對象編程的三大特性:繼承、封裝(隱藏)、多態。
封裝(隱藏)
隱藏對象的屬性和實現細節,只對外提供必要的方法。相當於將“細節封裝起來”,只 對外暴露“相關調用方法”。
通過前面學習的“私有屬性、私有方法”的方式,實現“封裝”。Python 追求簡潔的語法,沒有嚴格的語法級別的“訪問控制符”,更多的是依靠程序員自覺實現。
繼承
繼承可以讓子類具有父類的特性,提高了代碼的重用性。 從設計上是一種增量進化,原有父類設計不變的情況下,可以增加新的功能,或者改進 已有的算法。
多態
多態是指同一個方法調用由於對象不同會產生不同的行為。如:同樣是休息方法,人不同休息方法不同。張三休息是睡覺,李四休息是玩遊戲。
二:繼承
繼承是面向對象程序設計的重要特征,也是實現“代碼復用”的重要手段。
一個新類繼承自一個設計好的類,就直接具備了已有類的特征,就大大降低了工作難度。已有的類我們稱為“父類或者基類”,新的類我們稱為“子類或者派生類”。
(一)語法格式:
Python支持多重繼承,一個子類可以繼承多個父類。繼承的語法格式如下:
class 子類類名(父類 1[,父類 2,...]):
類體
如果在類定義中沒有指定父類,則默認父類是object 類。也就是說,object 是所有類的父 類,裏面定義了一些所有類共有的默認實現,比如:__new__()。
定義子類時,必須在其構造函數中調用父類的構造函數。調用格式如下: 父類名.__init__(self, 參數列表)
【操作】
#測試繼承 class Person: def __init__(self,name,age): self.name = name self.__age = age def say_age(self):print(self.name,‘的年齡是:‘,self.__age) class Student(Person): def __init__(self,name,age,score): self.score = score Person.__init__(self,name,age) #構造函數中包含調用父類構造函數,必須顯式的調用父類的__init__(),根據需要不是必須 s = Student(‘jack‘,18,100) s.say_age() #print(dir(s))
運行結果:
jack 的年齡是: 18
(二)類成員的繼承和重寫
1. 成員繼承:子類繼承了父類除構造方法之外的所有成員。
2. 方法重寫:子類可以重新定義父類中的方法,這樣就會覆蓋父類的方法,也稱為“重寫”
【操作】繼承和重寫
#測試繼承和重寫 class Person: def __init__(self,name,age): self.name = name self.age = age def say_age(self): print(self.name,‘的年齡是:‘,self.age) def say_name(self): print(‘我是:‘,self.name) class Student(Person): def __init__(self,name,age,score): self.score = score Person.__init__(self,name,age) #構造函數中包含調用父類構造函數 def say_score(self): print(self.name,‘的分數是:‘,self.score) def say_name(self): #重寫父類方法 print(‘報告老師,我是:‘,self.name) s = Student(‘jack‘,18,100) s.say_age() s.say_score() s.say_name()
運行結果:
jack 的年齡是: 18
jack 的分數是: 100
報告老師,我是: jack
(三)查看類的繼承層次結構
通過類的方法 mro()或者類的屬性__mro__可以輸出這個類的繼承層次結構
【操作】查看類的繼承層次結構
#查看類的繼承層次結構 class A: pass class B(A): pass class C(B): pass print(C.mro())
運行結果:
[<class ‘__main__.C‘>, <class ‘__main__.B‘>, <class ‘__main__.A‘>, <class ‘object‘>]
【說明】C-->B-->A-->object。
(四)Object根類
object 類是所有類的父類,因此所有的類都有object 類的屬性和方法。
dir()查看對象屬性:
內置函數 dir(),他可以讓我們方便的看到指定對象所有的 屬性。
【操作】查看對象所有屬性以及和object 進行比對
#查看對象的所有屬性以及和Object進行對比 class Person: def __init__(self,name,age): self.name = name self.age = age def say_age(self): print(self.name,‘的年齡是:‘,self.age) obj = object() p = Person(‘jack‘,18) print(dir(obj)) print(dir(p))
運行結果:
[‘__class__‘, ‘__delattr__‘, ‘__dir__‘, ‘__doc__‘, ‘__eq__‘, ‘__format__‘, ‘__ge__‘, ‘__getattribute__‘, ‘__gt__‘, ‘__hash__‘, ‘__init__‘, ‘__init_subclass__‘, ‘__le__‘, ‘__lt__‘, ‘__ne__‘, ‘__new__‘, ‘__reduce__‘, ‘__reduce_ex__‘, ‘__repr__‘, ‘__setattr__‘, ‘__sizeof__‘, ‘__str__‘, ‘__subclasshook__‘]
[‘__class__‘, ‘__delattr__‘, ‘__dict__‘, ‘__dir__‘, ‘__doc__‘, ‘__eq__‘, ‘__format__‘, ‘__ge__‘, ‘__getattribute__‘, ‘__gt__‘, ‘__hash__‘, ‘__init__‘, ‘__init_subclass__‘, ‘__le__‘, ‘__lt__‘, ‘__module__‘, ‘__ne__‘, ‘__new__‘, ‘__reduce__‘, ‘__reduce_ex__‘, ‘__repr__‘, ‘__setattr__‘, ‘__sizeof__‘, ‘__str__‘, ‘__subclasshook__‘, ‘__weakref__‘, ‘age‘, ‘name‘, ‘say_age‘]
從上面我們可以發現這樣幾個要點:
1. Person對象增加了六個屬性: __dict__ __module__ __weakref__ age name say_age
2. object的所有屬性,Person 類作為object 的子類,顯然包含了所有的屬性。
3. 我們打印age、name、say_age,發現say_age 雖然是方法,實際上也是屬性。只不過, 這個屬性的類型是“method”而已。
age <class ‘int‘>
name <class ‘str‘>
say_age <class ‘method‘>
重寫__str__()方法
object 有一個__str__()方法,用於返回一個對於“對象的描述”,對應於內置函數 str() 經常用於print()方法,幫我們查看對象的信息。__str__()可以重寫。
【操作】
#重寫__str__()方法 class Person: def __init__(self,name,age): self.name = name self.__age = age def __str__(self): ‘‘‘將對象轉化成一個字符串,一般用於print()方法‘‘‘ return ‘{0}的年齡是:{1}‘.format(self.name,self.__age) p = Person(‘jack‘,18) print(p)
運行結果:
jack的年齡是:18
(一)Python入門-6面向對象編程:07面向對象三大特征(封裝、繼承、多態)-繼承