封裝
封裝其實是一種思想,將事物狀態和功能裝進一個容器,那么這個容器在python中就是類,由這個類產生的對象都擁有類的屬性和功能
在面向對象的思想中,推崇將具有某些共同特征的事物歸為一類,那么這些事物就可以看做是這個類的具象化對象,但是允許個體擁有不同的特征
例如:你和我都是人,都具有人的基本功能,那么我們就是人的對象,我和你的名字可以不一樣,性別可以不一樣,但本質上我們都是人類
在前面我們說到,類不是實實在在存在的,是一系列擁有相似屬性和功能的事物的抽離。那么在定義類和類的屬性、功能上實際就是把這些屬性和功能封裝進類里面,抽離相似屬性和功能并把它們放到類里,這種思想就是封裝
class Animal:
dog = “”
human = “”
...
def eat(self):
print("enting")
def sleep(self):
print("sleeping")
動物類封裝進了dog、human等等屬性,封裝了eat、sleep等功能,這些都屬于Animal類共有的一些屬性和功能
?
繼承
?
繼承的概念源于對現實事物的模擬,在人類的概念中,人類下面還有女人、男人、小孩、大人等細分概念,那么女人就是人類的擴展,人類概念就是女人概念的爸爸,女人概念除了擁有人類的所有屬性和功能外還多了一個屬性就是性別,那么女人類和人類就有非常多的相同屬性和功能,回到編程中,這些高度相似或者相同的屬性和功能其實就是重復的代碼,繼承的出現就是為了避免重復寫大量代碼描述兩個屬性和功能高度重合的類。
例:
class human:
legs = 4
ear = 2
def? eat (self):
pass
class women:
legs =? 4
ear = 2
sex = “”
def eat (self):
pass
由human 和 women 類可以看出,他們有相同的屬性legs、ear和相同的功能eat(),如果在代碼里這么寫代碼將非常冗余,面向對象語言幾乎都有繼承的思想,如果用繼承來表示上面的代碼將會是:
class human:
legs = 4
ear = 2
def? eat?(self):
pass
?
class women(human):
sex = ""
這樣的話human就是繼承women,human就是women的父類,women就是human的子類,women既有自己的屬性sex,也擁有父類的所有屬性和功能。
具體實現和原理見:
多繼承
在python中允許多繼承關系,一個類可以同時繼承多個類,這樣它就擁有所有父類的屬性和方法
在python2中,沒有繼承任何類的類被稱為經典類,默認不繼承任何類
在python3中,所有的類默認繼承object,這種類被稱為新式類
菱形繼承
a繼承b,c,b,c由同時繼承d,那么繼承關系就形成閉環,此時a擁有的功能和屬性最多,d擁有的功能和屬性最少
菱形繼承會帶來屬性查找順序的問題,比如a的屬性name是繼承而來的,但不知道是b,c,d哪一個的,此時就會有查找順序,在python2和python中是不一樣的
python2中,是以深度查找為基本原則,即a->b->d->c,一直查找到繼承關系最深的那一層
python3中,是以廣度查找為基本原則的,即a->b->c->d,先將分支都查找完,最后找最深的那一層
?
多態
由同一父類派生的不同子類對象都可以作為參數傳遞給某個函數去執行,并產生不同的結果,這種形態叫多態。
例:
class A:
def __init__(self,name):
self.name = name
class B(A):
pass
def pri_name(obj):
print(obj.name)
b1 = B("egon")
b2 = B("owen")
pri_name(b1)
pri_name(b2)
打印結果:
egon
owen
?
鴨子類型
兩個不相干的兩個類的對象可以將自身作為參數傳給同一個函數去調用執行,這樣的就是鴨子類型,在python里十分推崇鴨子類型,一個生物不知道它是不是鴨子,但它只要長得像鴨子,水里游泳像鴨子,那就認為它是鴨子
class A:
def __init__(self,name):
self.name = name
self.age = 18
class B:
def __init__(self,name):
self.name = name
self.sex = "female"
def pri_name(obj):
print(obj.name)
b1 = B("egon")
b2 = B("owen")
pri_name(b1)
pri_name(b2)
打印結果:
egon
owen
?