python入門(mén)3

繼承

雖然子類(lèi)Bosi沒(méi)有__init__()方法,但是父類(lèi)有,所以子類(lèi)在繼承父類(lèi)時(shí),這個(gè)方法也被繼承了。所以只要?jiǎng)?chuàng)建了Bosi的對(duì)象,就默認(rèn)執(zhí)行繼承過(guò)來(lái)的__init__()方法。

子類(lèi)在繼承的時(shí)候,在定義類(lèi)的時(shí)候,小括號(hào)()中為父類(lèi)的名字,父類(lèi)的屬性、方法都會(huì)繼承給子類(lèi)。

當(dāng)子類(lèi)和父類(lèi)擁有同一方法是,調(diào)用誰(shuí)的方法。觀察如下代碼:

子類(lèi)和父類(lèi)同有__init__()方法,在對(duì)象調(diào)用時(shí),子類(lèi)的__init__()方法會(huì)覆蓋父類(lèi)的__init__()方法。

關(guān)于對(duì)象調(diào)用時(shí)的地址和繼承調(diào)用時(shí)的地址,觀察如下代碼:

可以看出,他們的地址是一樣的。

私有的屬性和方法都不能被繼承,也不能被對(duì)象直接調(diào)用,可以通過(guò)方法訪(fǎng)問(wèn)。一般情況下,私有的屬性和方法都是不對(duì)外公布的,往往用來(lái)做內(nèi)部的事情,起到安全的作用。

一個(gè)子類(lèi)不僅可以單一繼承,也可以多繼承。當(dāng)一個(gè)子類(lèi)有多個(gè)父類(lèi)時(shí),具體的操作代碼如下:

從以上的例子可以看出,當(dāng)存在多個(gè)父類(lèi)時(shí),且這些父類(lèi)擁有同名的方法,子類(lèi)會(huì)按照繼承的順序去調(diào)用方法,而不會(huì)發(fā)生父類(lèi)方法的重寫(xiě)。

如果想子類(lèi)父類(lèi)都有該方法,如何重寫(xiě)子類(lèi)覆蓋的父類(lèi)方法,方式有兩種。具體代碼如下:

使用super().父類(lèi)方法名()可以實(shí)現(xiàn)重寫(xiě)父類(lèi)方法,但因?yàn)槭前蠢^承順序調(diào)用的父類(lèi)方法,所以父類(lèi)F2()中的test ()方法不會(huì)被調(diào)用。如何在不修改繼承順序的情況下調(diào)用父類(lèi)F2()中的test ()方法。代碼如下:

通過(guò)父類(lèi)名.父類(lèi)方法名(self)可以實(shí)現(xiàn)想要訪(fǎng)問(wèn)的父類(lèi)方法。

對(duì)于屬性的賦值,如果在子類(lèi)中對(duì)特殊屬性賦值時(shí),將會(huì)覆蓋父類(lèi)對(duì)于共有屬性的定義,所以可以采用以上的方法對(duì)屬性賦值:

通過(guò)以上代碼,不僅完成了對(duì)Dog()這一類(lèi)特殊屬性的賦值,也完成了父類(lèi)Animal()的通用屬性的賦值。

類(lèi)屬性、實(shí)例屬性

class?Student():

name?=?'Tony'

__age?=?18

stu1?=?Student()

print(stu1.name)輸出Tony

print(Student.name)輸出Tony

print(stu1.__age)報(bào)錯(cuò),不能在類(lèi)外通過(guò)實(shí)例對(duì)象訪(fǎng)問(wèn)私有的類(lèi)屬性

print(Student.__age)報(bào)錯(cuò),不能在類(lèi)外通過(guò)類(lèi)對(duì)象訪(fǎng)問(wèn)私有的類(lèi)屬性

class?People(object):

#類(lèi)屬性

address?=?'山東'

def?__init__(self):

self.name?=?'xiaowang'

self.age?=?20

p?=?People()

p.age?=12

print(p.address)

print(p.name)

print(p.age)

print(People.address)

print(People.name)

print(People.age)

輸出結(jié)果如上所示。如何通過(guò)實(shí)例對(duì)象修改類(lèi)屬性?

如果需要在類(lèi)外修改類(lèi)屬性,必須通過(guò)類(lèi)對(duì)象去引用然后進(jìn)行修改。如果通過(guò)實(shí)例對(duì)象去引用,會(huì)產(chǎn)生一個(gè)同名的實(shí)例屬性,這種方式修改的是實(shí)例屬性,不會(huì)影響到類(lèi)屬性,并且之后如果通過(guò)實(shí)例對(duì)象去引用該名稱(chēng)的屬性,實(shí)例屬性會(huì)強(qiáng)制屏蔽掉類(lèi)屬性,即引用的是實(shí)例屬性,除非刪除了該實(shí)例屬性。

類(lèi)方法

是類(lèi)對(duì)象所擁有的方法,需要用修飾器@classmethod來(lái)標(biāo)識(shí)其為類(lèi)方法,對(duì)于類(lèi)方法,第一個(gè)參數(shù)必須是類(lèi)對(duì)象,一般以cls作為第一個(gè)參數(shù)(當(dāng)然可以用其他名稱(chēng)的變量作為其第一個(gè)參數(shù),但是大部分人都習(xí)慣以'cls'作為第一個(gè)參數(shù)的名字,就最好用'cls'了),能夠通過(guò)實(shí)例對(duì)象和類(lèi)對(duì)象去訪(fǎng)問(wèn)。

class?People(object):

country?=?'china'

#類(lèi)方法,用classmethod來(lái)進(jìn)行修飾

@classmethod

def?getCountry(cls):

return?cls.country

p?=?People()

print(p.getCountry())#可以用過(guò)實(shí)例對(duì)象引用

print(People.getCountry())????#可以通過(guò)類(lèi)對(duì)象引用

類(lèi)方法還可以對(duì)類(lèi)屬性進(jìn)行修改

class?People(object):

country?=?'china'

#類(lèi)方法,用classmethod來(lái)進(jìn)行修飾

@classmethod

def?getCountry(cls):

return?cls.country

@classmethod

def?setCountry(cls,country):

cls.country?=?country

p?=?People()

print(p.getCountry())?????????#可以用過(guò)實(shí)例對(duì)象引用

print(People.getCountry())????#可以通過(guò)類(lèi)對(duì)象引用

p.setCountry('japan')

print(p.getCountry())

print(People.getCountry())

靜態(tài)方法

需要通過(guò)修飾器@staticmethod來(lái)進(jìn)行修飾,靜態(tài)方法不需要多定義參數(shù)

class?People(object):

country?=?'china'

@staticmethod

#靜態(tài)方法

def?getCountry():

return?People.country

print(People.getCountry())

從類(lèi)方法和實(shí)例方法以及靜態(tài)方法的定義形式就可以看出來(lái),類(lèi)方法的第一個(gè)參數(shù)是類(lèi)對(duì)象cls,那么通過(guò)cls引用的必定是類(lèi)對(duì)象的屬性和方法;而實(shí)例方法的第一個(gè)參數(shù)是實(shí)例對(duì)象self,那么通過(guò)self引用的可能是類(lèi)屬性、也有可能是實(shí)例屬性(這個(gè)需要具體分析),不過(guò)在存在相同名稱(chēng)的類(lèi)屬性和實(shí)例屬性的情況下,實(shí)例屬性?xún)?yōu)先級(jí)更高。靜態(tài)方法中不需要額外定義參數(shù),因此在靜態(tài)方法中引用類(lèi)屬性的話(huà),必須通過(guò)類(lèi)對(duì)象來(lái)引用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容