Python是面向對象的語言,也支持面向對象編程的三大特性:繼承、封裝(隱藏)、多態。程序員
封裝(隱藏)算法
隱藏對象的屬性和實現細節,只對外提供必要的方法。至關於將「細節封裝起來」,只 對外暴露「相關調用方法」。編程
經過前面學習的「私有屬性、私有方法」的方式,實現「封裝」。Python 追求簡潔的語法,沒有嚴格的語法級別的「訪問控制符」,更多的是依靠程序員自覺實現。ssh
繼承函數
繼承可讓子類具備父類的特性,提升了代碼的重用性。 從設計上是一種增量進化,原有父類設計不變的狀況下,能夠增長新的功能,或者改進 已有的算法。學習
多態測試
多態是指同一個方法調用因爲對象不一樣會產生不一樣的行爲。如:一樣是休息方法,人不一樣休息方法不一樣。張三休息是睡覺,李四休息是玩遊戲。spa
繼承是面向對象程序設計的重要特徵,也是實現「代碼複用」的重要手段。設計
一個新類繼承自一個設計好的類,就直接具有了已有類的特徵,就大大下降了工做難度。已有的類咱們稱爲「父類或者基類」,新的類咱們稱爲「子類或者派生類」。code
(一)語法格式:
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