python中的類與對象2

python中的類與對象2

  • 復(fù)習(xí)
class Chinese:  # 類的創(chuàng)建
    eye = 'black'  # 類屬性的創(chuàng)建

    def __init__(self,hometown):  # 類的初始化方法
        self.hometown = hometown  # 實例屬性的創(chuàng)建
        print('程序持續(xù)更新中……')  # 初始化中的語句
    
    def born(self):  # 實例方法的創(chuàng)建
        print('我生在%s。'%(self.hometown))  # 方法的具體語句

bazhan = Chinese('廣東')  # 類的實例化
print(bazhan.eye)  # 打印實例的屬性(從類傳遞的)
bazhan.born()  # 實例方法的調(diào)用

類的繼承和定制

繼承

  • 我們通過事物的歸屬關(guān)系删掀,使信息的傳遞更為高效翔冀。聽到“Python是一種計算機語言”,我們就知道Python可以編程披泪;看到“云浮市在廣東省”纤子,我們就明白云浮市在中國南方
  • 我們也可以用一句話,讓計算機知道:A類屬于B類款票,自然也擁有了B類的所有屬性和方法控硼。這句話在編程里就是:A類繼承了B類。
繼承
  • 在Python中艾少,我們的習(xí)慣表述是:A類是B類的子類卡乾,而B類是A類的父類(或超類)。
  • 類的繼承缚够,讓子類擁有了父類擁有的所有屬性和方法幔妨。

定制

  • 只有繼承的話,子類只是父類的復(fù)制而已谍椅。我們需要了解另一個重要的概念:類的定制误堡。
  • 子類也可以在繼承的基礎(chǔ)上進行個性化的定制,包括:(1)創(chuàng)建新屬性雏吭、新方法锁施;(2)修改繼承到的屬性或方法。
  • 類的定制杖们,不僅可以讓子類擁有新的功能悉抵,還能讓它有權(quán)修改繼承到的代碼
  • 當(dāng)我們談定制時,已經(jīng)包含了繼承胀莹。畢竟基跑,類的定制的前提是繼承,而定制的加入讓類的繼承不僅僅只是單純的復(fù)制而已描焰。這也是我們創(chuàng)建子類的意義

類的繼承如何寫

繼承的基礎(chǔ)語法

繼承的基礎(chǔ)語法
  • 子類繼承的屬性和方法媳否,也會傳遞給子類創(chuàng)建的實例
# 例
class Chinese:
    eye = 'black'

    def eat(self):
        print('吃飯栅螟,選擇用筷子。')

class Cantonese(Chinese):  
# 通過繼承篱竭,Chinese類有的力图,Cantonese類也有
    pass

# 驗證子類可以繼承父類的屬性和方法,進而傳遞給子類創(chuàng)建的實例
yewen = Cantonese()  
# 子類創(chuàng)建的實例掺逼,從子類那間接得到了父類的所有屬性和方法
print(yewen.eye)  
# 子類創(chuàng)建的實例吃媒,可調(diào)用父類的屬性
yewen.eat()  
# 子類創(chuàng)建的實例,可調(diào)用父類的方法
  • 通過一個小括號吕喘,子類就能輕輕松松地?fù)碛懈割愃鶕碛械囊磺凶改恰2挥脧?fù)制大段大段的代碼,只要一個括號氯质,就能復(fù)用整塊代碼募舟。

  • 很多類在創(chuàng)建時也不帶括號,如class Chinese闻察,實際上拱礁,class Chinese:在運行時相當(dāng)于class Chinese(object):。而object辕漂,是所有類的父類呢灶,我們將其稱為根類(可理解為類的始祖)。
  • 我們可以用一個函數(shù)來驗證這一點:函數(shù)isinstance()钉嘹,可以用來判斷某個實例是否屬于某個類鸯乃。
print(isinstance(1,int))
# 判斷1是否為整數(shù)類的實例
print(isinstance(1,str))

print(isinstance(1,(int,str)))
# 判斷實例是否屬于元組里幾個類中的一個
# 閱讀完代碼再運行。
class Chinese:
    pass

class Cantonese(Chinese):
    pass

gonger = Chinese()
# 宮二跋涣,電影《一代宗師》女主飒责,生于東北
yewen = Cantonese()
# 葉問,電影《一代宗師》男主仆潮,生于廣東

print('\n驗證1:子類創(chuàng)建的實例同時也屬于父類')
print(isinstance(gonger,Chinese))  
print(isinstance(yewen,Chinese))  

print('\n驗證2:父類創(chuàng)建的實例不屬于子類。')
print(isinstance(gonger,Cantonese))

print('\n驗證3:類創(chuàng)建的實例都屬于根類遣臼。')
print(isinstance(gonger,object))  
print(isinstance(yewen,object))
各級實例與類的關(guān)系
  • 在類的繼承中性置,不僅子類屬于父類,子類所創(chuàng)建的實例實際上也同時屬于父類揍堰。
  • 父類可以被無限個子類所繼承(這一點好比類的屬性方法可以傳遞給無限個實例)

類的繼承之多層繼承

# 例
class Earthman:
    eye_number = 2

# 中國人繼承了地球人
class Chinese(Earthman):
    eye_color = 'black'

# 廣東人繼承了中國人鹏浅,同時也繼承了地球人。
class Cantonese(Chinese):
    pass

yewen = Cantonese()
print(yewen.eye_number)
print(yewen.eye_color)
  • 實例yewen可以調(diào)用父類Chinese和父類的父類Earthman中的屬性屏歹∫遥可得結(jié)論:子類創(chuàng)建的實例可調(diào)用所有層級父類的屬性和方法。
  • 多層繼承蝙眶,屬于繼承的==深度拓展==季希。而下面要講的多重繼承褪那,則是繼承的寬度拓展。

類的繼承之多重繼承

  • 一個類式塌,可以同時繼承多個類博敬,語法為class A(B,C,D):
  • 假設(shè)我們將“出生在江蘇,定居在廣東的人”設(shè)為一個類Yuesu峰尝,那么偏窝,它的創(chuàng)建語句則為class Yuesu(Yue,Su)。
  • class Yuesu(Yue,Su)括號里Yue和Su的順序是有講究的武学。和子類更相關(guān)的父類會放在更左側(cè)
  • “出生在江蘇祭往,定居在廣東的人”在穿著和飲食等方面會更接近廣東人,所以將 Yue 放在 Su 的左側(cè)
  • 所以火窒,廣東人創(chuàng)建的實例在調(diào)用屬性和方法時硼补,會先在左側(cè)的父類中找,找不到才會去右側(cè)的父類找沛鸵。(可理解為“就近原則”)
class Su:
    born_city = 'Jiangsu'
    wearing = 'thick'  # 穿得較厚

    def diet(self):
        print('我們愛吃甜括勺。')

class Yue:
    settle_city = 'Guangdong'
    wearing = 'thin'  # 穿得較薄

    def diet(self):
        print('我們吃得清淡。')

class Yuesu(Yue,Su):
    pass

xiaoming = Yuesu()
print(xiaoming.wearing)
print(xiaoming.born_city)
xiaoming.diet()
# 越靠近子類(即越靠左)的父類曲掰,越親近疾捍,越優(yōu)先考慮。子類調(diào)用屬性和方法時栏妖,會先在靠左的父類里找乱豆,找不到才往右找。
多層繼承和多重繼承
  • 多層繼承和多重繼承的結(jié)合吊趾,讓繼承的類擁有更多的屬性和方法宛裕,且能更靈活地調(diào)用。進而论泛,繼承的力量也得以放大了很多倍揩尸。

  • 練習(xí)
習(xí)題
class C0:
    name = 'C0'

class C2(C0):
    num = 2

class C1:
    num = 1

class C3:
    name = 'C3'

class C4(C1,C2,C3):
    pass

ins = C4()
print(ins.name) # 打印出C0
print(ins.num) # 打印出1
  • 可以發(fā)現(xiàn)就近原則中的一個細(xì)節(jié):多重繼承中,若某父類還有父類的話屁奏,會先繼續(xù)往上找到頂岩榆。例如代碼中的ins.name調(diào)用的是C2的父類C0的值而非 C3。

類的定制如何寫

定制坟瓢,可以新增代碼

# 例
class Chinese:
    eye = 'black'

    def eat(self):
        print('吃飯勇边,選擇用筷子。')

class Cantonese(Chinese):  # 類的繼承
    native_place = 'guangdong'  # 類的定制

    def dialect(self):  # 類的定制
        print('我們會講廣東話折联。')

yewen = Cantonese()
print(yewen.eye)
# 父類的屬性能用
print(yewen.native_place)
# 子類的定制屬性也能用
yewen.eat()
# 父類的方法能用
yewen.dialect()
# 子類的定制方法也能用
  • 我們可以在子類下新建屬性或方法粒褒,讓子類可以用上父類所沒有的屬性或方法。這種操作诚镰,屬于定制中的一種:新增代碼奕坟。

定制祥款,也可重寫代碼

  • 例題:已知中國的陸地面積,也知道廣東的陸地面積占比為1.88%执赡。
class Chinese:
    def land_area(self,area):
        print('我們居住的地方镰踏,陸地面積是%d萬平方公里左右。'% area)

class Cantonese(Chinese):
    # 直接對方法進行重寫
    def land_area(self,area):
        print('我們居住的地方沙合,陸地面積是%d萬平方公里左右奠伪。'% int(area * 0.0188))
gonger = Chinese()
yewen = Cantonese()
gonger.land_area(960)
yewen.land_area(960)
        #兩個類都有個各自的land_area()方法,但有些冗余
  • 優(yōu)化代碼
class Chinese:

    def land_area(self,area):
        print('我們居住的地方,陸地面積是%d萬平方公里左右首懈。'% area)

class Cantonese(Chinese):
    # 間接對方法進行重寫
    def land_area(self, area, rate = 0.0188):
        Chinese.land_area(self, area * rate)
        # 直接繼承父類方法绊率,再調(diào)整參數(shù)。

gonger = Chinese()
yewen = Cantonese()
gonger.land_area(960)
yewen.land_area(960)
  • 子類繼承父類方法的操作是在def語句后接父類.方法(參數(shù))究履,如上述代碼的第八滤否、九行。
  • 父類方法land_area中的說法改變最仑,子類也不用去動藐俺,因為子類直接繼承了父類的方法。只不過泥彤,在繼承的基礎(chǔ)上欲芹,通過參數(shù)的調(diào)整完成了定制。
  • 參數(shù)的調(diào)整吟吝,可以增加參數(shù)(如 rate)菱父,也可以改變參數(shù)的默認(rèn)值
class Chinese:

    def land_area(self,area):
        print('我們居住的地方,陸地面積是%d萬平方公里左右剑逃。' % area)

class Cantonese(Chinese):
    # 為參數(shù) area 設(shè)置默認(rèn)值浙宜。
    def land_area(self, area = 960, rate = 0.0188):
        Chinese.land_area(self, area * rate)

yewen = Cantonese()
yewen.land_area()
# 兩個參數(shù)都有默認(rèn)值,所以可以這么調(diào)用蛹磺。
  • 例題:通過參數(shù)默認(rèn)值的改變粟瞬,完成子類的定制,讓程序的運行結(jié)果為“雷猴萤捆!歡迎來到廣東亩钟。”
class Chinese:

    def __init__(self, greeting = '你好', place = '中國'):
        self.greeting = greeting
        self.place = place

    def greet(self):
        print('%s鳖轰!歡迎來到%s。' % (self.greeting, self.place))

class Cantonese(Chinese):

    def __init__(self, greeting = '雷猴', place = '廣東'):
        Chinese.__init__(self, greeting, place)
    
yewen = Cantonese()
yewen.greet()

練習(xí)

練習(xí)一

  • 練習(xí)要求:每個人都有好幾個不同的身份扶镀,且不同身份都附帶一些特定的特征(屬性)和行為(方法)蕴侣。例如,有這樣一群人:在學(xué)校時被歸在老師臭觉,臉是嚴(yán)肅的昆雀;親子關(guān)系中(parenthood)則被歸到父親辱志,臉是甜蜜的。
class Teacher:
    face = 'serious'
    job = 'teacher'


class Father:
    face = 'sweet'
    parenthood = 'dad'


class TeacherMore(Teacher, Father):
    pass

class FatherMore(Father, Teacher):
    face = 'gentle'

time3 = TeacherMore()
time4 = FatherMore()
print(time3.face)
print(time4.face)

練習(xí)二

  • 練習(xí)要求:練習(xí)會先提供一個類狞膘,用以記錄學(xué)生學(xué)習(xí) Python 的投入時間和有效時間揩懒。需要你創(chuàng)建一個子類,為某一類學(xué)生提供定制化的記錄方案挽封。
class Student:
    def __init__(self, name, job=None, time=0.00, time_effective=0.00): 
        self.name = name
        self.job = job
        self.time = time
        self.time_effective = time_effective

    def count_time(self, hour, rate):
        self.time += hour
        self.time_effective += hour * rate

class Programmer(Student):
    def __init__(self, name):
        Student.__init__(self, name, job='programmer', time=0.00, time_effective=0.00)

    def count_time(self, hour, rate=1):
        Student.count_time(self, hour, rate)

student1 = Student('韓梅梅')
student2 = Programmer('李雷')
print(student1.job)
print(student2.job)
student1.count_time(10, 0.8)
student2.count_time(10)
print(student1.time_effective)
print(student2.time_effective)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末已球,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子辅愿,更是在濱河造成了極大的恐慌智亮,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件点待,死亡現(xiàn)場離奇詭異阔蛉,居然都是意外死亡,警方通過查閱死者的電腦和手機癞埠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門状原,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人苗踪,你說我怎么就攤上這事颠区。” “怎么了徒探?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵瓦呼,是天一觀的道長。 經(jīng)常有香客問我测暗,道長央串,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任碗啄,我火速辦了婚禮质和,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘稚字。我一直安慰自己饲宿,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布胆描。 她就那樣靜靜地躺著瘫想,像睡著了一般。 火紅的嫁衣襯著肌膚如雪昌讲。 梳的紋絲不亂的頭發(fā)上国夜,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天,我揣著相機與錄音短绸,去河邊找鬼车吹。 笑死筹裕,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的窄驹。 我是一名探鬼主播朝卒,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼乐埠!你這毒婦竟也來了抗斤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤饮戳,失蹤者是張志新(化名)和其女友劉穎豪治,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扯罐,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡负拟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了歹河。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掩浙。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖秸歧,靈堂內(nèi)的尸體忽然破棺而出厨姚,到底是詐尸還是另有隱情,我是刑警寧澤键菱,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布谬墙,位于F島的核電站,受9級特大地震影響经备,放射性物質(zhì)發(fā)生泄漏拭抬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一侵蒙、第九天 我趴在偏房一處隱蔽的房頂上張望造虎。 院中可真熱鬧,春花似錦纷闺、人聲如沸算凿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽氓轰。三九已至,卻和暖如春浸卦,著一層夾襖步出監(jiān)牢的瞬間戒努,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留储玫,地道東北人。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓萤皂,卻偏偏與公主長得像撒穷,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子裆熙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348