聚沙成塔--爬蟲(chóng)系列(八)(物以「類(lèi)」聚,人以群分)

版權(quán)聲明:本文為作者原創(chuàng)文章,可以隨意轉(zhuǎn)載,但必須在明確位置標(biāo)明出處!!!

文章講到這里,我不得不想先把面向?qū)ο蟮木幊讨v了,否則我們的代碼看上去將會(huì)越來(lái)越亂,越來(lái)也不易管理。

什么是類(lèi)

類(lèi)是對(duì)現(xiàn)實(shí)生活中一類(lèi)具有共同特征的事物的抽象。所有的事物都來(lái)源于生活,不管哪行哪業(yè)都是為了解決我們生活中的問(wèn)題,編程亦是。

類(lèi)的三大屬性

  • 封裝:類(lèi)將具有共同特征的一類(lèi)事物抽象在一起,比如水果類(lèi)包含蘋(píng)果、香蕉、梨子、西瓜等等,這些具有同樣屬性的我們可以歸為到一個(gè)類(lèi)里
封裝
  • 繼承:類(lèi)是有繼承關(guān)系的,繼承關(guān)系的作用是讓子類(lèi)具有自己特有的行為,不如西瓜是它是繼承水果的,那么西瓜它可以定義自己特有的行為、屬性,像有籽西瓜、無(wú)籽西瓜兩種屬性,子類(lèi)可以繼承父類(lèi)的公有方法和屬性。什么意思呢,就像你可以繼承你爸媽的財(cái)產(chǎn),但是你不能繼承你爸媽的朋友,或隱私方面的東西,隱私方面的東西在編程語(yǔ)言中我們稱(chēng)之為private(私有的),私有的東西子女是不可以繼承的。還有一點(diǎn)就是繼承可以是多層級(jí)結(jié)構(gòu)的,就像你可以繼承你爸媽的財(cái)產(chǎn),你兒子也能繼承你的財(cái)產(chǎn),那么你兒子的財(cái)產(chǎn)就包含了你的和爸媽的財(cái)產(chǎn)。
繼承
  • 多態(tài):從字面意思理解就是多鐘形態(tài),專(zhuān)業(yè)的解釋就是:多態(tài)性是允許你將父對(duì)象設(shè)置成為一個(gè)或更多的他的子對(duì)象相等的技術(shù),賦值之后,父對(duì)象就可以根據(jù)當(dāng)前賦值給它的子對(duì)象的特性以不同的方式運(yùn)作。專(zhuān)業(yè)解釋我想信大多初學(xué)者都不明白啥意思。舉個(gè)例子:某公司A和幾個(gè)快遞服務(wù)公司有合作關(guān)系,比如順風(fēng)、中通、申通。順風(fēng)快遞給A公司打電話(huà)說(shuō)你們公司今年的快件服務(wù)我包了,那么從簽訂合同日起,A公司的所有快遞服務(wù)都會(huì)自動(dòng)的通過(guò)順風(fēng)快遞走,同理,明年若是中通簽了合同,那么A公司明年的快遞服務(wù)都自動(dòng)的走中通快遞服務(wù)。我相信講到這里大家應(yīng)該能明白多態(tài)是什么意思了,多態(tài)說(shuō)百了就是種接口服務(wù)。就像公司A它提供了一個(gè)快遞服務(wù)接口,那么只要是快遞公司都可以去調(diào)用這個(gè)接口。調(diào)用接口后就按照自己公司的物流走就是了。
多態(tài)-擎天柱

類(lèi)的定義

class myclass(object):
    class_suite

類(lèi)的定義主要是使用關(guān)鍵字「class」,類(lèi)定義好了以后可以在類(lèi)里定義方法,變量;專(zhuān)業(yè)術(shù)語(yǔ)稱(chēng)之為行為,屬性。

類(lèi)的繼承

class A(object):
    def foo(self):
        print('this is A')

class B(A):
    pass

class C(B):
    pass

if __name__ == '__main__':
    cc = C()
    cc.foo()

類(lèi)C繼承類(lèi)B,類(lèi)B繼承類(lèi)A,pass關(guān)鍵字的意思是什么也不做,在類(lèi)中定義方法第一個(gè)參數(shù)都是self,表示類(lèi)本身,如果你接觸過(guò)C/C++語(yǔ)言,那么這里的self就跟C/C++語(yǔ)言里的this指針一個(gè)意思。

  • 「if _name_ == '_main_'」:這一句是入口函數(shù),當(dāng)我們運(yùn)行該程序時(shí)解釋器從這里開(kāi)始執(zhí)行。
  • 「cc = C()」:創(chuàng)建一個(gè)C類(lèi)型的實(shí)例,只有創(chuàng)建了實(shí)例才能去調(diào)用類(lèi)中的方法和屬性,
  • 「cc.foo()」: 這一句就充分體現(xiàn)了類(lèi)的繼承關(guān)系, 類(lèi)C沒(méi)有定義foo()方法,當(dāng)時(shí)它繼承了B,B又繼承了A,所以C自然也就繼承了A的foo方法,這就是繼承的好處,如果父類(lèi)提供了你需要的方法,你就不需要再去重復(fù)定義實(shí)現(xiàn)了。

繼承中的覆蓋(Overriding)

繼承中的覆蓋是什么意思呢,如果類(lèi)B也要實(shí)現(xiàn)方法foo,當(dāng)時(shí)它的方法和類(lèi)A的行為是不是一樣的,那我們就稱(chēng)這種行為為覆蓋

class A(object):
    def foo(self):
        print('this is A')

class B(A):
    def foo(self):
        print('this is B')

class C(B):
    def foo(self):
        print('this is C')

if __name__ == '__main__':
    cc = C()
    cc.foo()

結(jié)果將會(huì)輸出‘this is C’,類(lèi)C中的foo方法就是C類(lèi)特有的行為。那么到這里有認(rèn)真思考過(guò)的同學(xué)就要問(wèn),我又想有自己的行為,也想調(diào)用父類(lèi)的行為怎么辦呢,看下面的代碼

class A(object):
    def foo(self):
        print('this is A')

class B(A): 
    def foo(self):
        A.foo(self)
        print('this is B')

class C(B):
    def foo(self):
        B.foo(self)
        print('this is C')

if __name__ == '__main__':
    cc = C()
    cc.foo()

執(zhí)行的結(jié)果將會(huì)輸出

this is A
this is B
this is C

super的使用

上面例子的寫(xiě)法雖然可以達(dá)到目的,但不是一種好的寫(xiě)法,它的不好之處在于若在你的工程中有大量的此種寫(xiě)法,那么若是類(lèi)的繼承關(guān)系變了,那你不得不在整個(gè)工程中去查找修改相應(yīng)的代碼,這里我們使用super的方式改寫(xiě)它。

class A(object):
    def foo(self):
        print('this is A')

class B(A): 
    def foo(self):
        super(B, self).foo()
        print('this is B')

class C(B):
    def foo(self):
        super(C, self).foo()
        print('this is C')

if __name__ == '__main__':
    cc = C()
    cc.foo()

輸出的結(jié)果和上面一致,使用super()的漂亮之處在于,你不需要明確給出任何基類(lèi)名字...“跑腿事兒”,它幫你干了!使用super()的重點(diǎn),是你不需要明確提供父類(lèi)。這意味著如果你改變了類(lèi)繼承關(guān)系,你只需要改一行代碼(class 語(yǔ)句本身)而不必在大量代碼中去查找所有被修改的那個(gè)類(lèi)的名字。

構(gòu)造器init()

構(gòu)造器也叫構(gòu)造函數(shù),當(dāng)一個(gè)類(lèi)實(shí)例化的時(shí)候它將會(huì)自動(dòng)調(diào)用該函數(shù),這里我們需要提點(diǎn)的是,在python中類(lèi)B繼承了類(lèi)A,他們都實(shí)現(xiàn)了_init_()函數(shù),那么當(dāng)類(lèi)B實(shí)例化的時(shí)候不會(huì)去調(diào)用類(lèi)A的構(gòu)造方法了,這個(gè)和C/C++,JAVA語(yǔ)言是不同的,大家要注意這點(diǎn)

class A(object):
    def __init__(self):
        print('this is A init')
    def foo(self):
        print('this is A')

class B(A): 
    def __init__(self):
        print('this is B init')
    def foo(self):
        super(B, self).foo()
        print('this is B')

class C(B):
    def __init__(self):
        print('this is C init')
    def foo(self):
        super(C, self).foo()
        print('this is C')

if __name__ == '__main__':
    cc = C()
    cc.foo()

執(zhí)行結(jié)果將會(huì)輸出

this is C init
this is A
this is B
this is C

可以看到它并沒(méi)有去調(diào)用A,B類(lèi)的構(gòu)造器init()方法,如果C不定義會(huì)輸出什么大家可以自己去試試

私有屬性,私有方法

在python中,類(lèi)中的所有方法和屬性默認(rèn)是‘public’共有的,可以被繼承的,那么如果想要屬性和方法不能被繼承怎么辦呢,那就是在屬性和方法的定義前加兩個(gè)下劃線(xiàn), 特別需要提點(diǎn)的是我們自己內(nèi)中定義的函數(shù)不要有想_xxx_()這種定義,這種定義是python內(nèi)建函數(shù)的定義,切記、切記。

class A(object):
   
    def __foo(self):
        print('this is A')

class B(A): 
   pass
   

class C(B):
   pass

if __name__ == '__main__':
    print(dir(C))
    cc = C()
    cc.__foo()

執(zhí)行結(jié)果將會(huì)出現(xiàn)下面錯(cuò)誤

Traceback (most recent call last):
  File "classtest.py", line 16, in <module>
    cc.__foo()
AttributeError: 'C' object has no attribute '__foo'

多態(tài)的實(shí)現(xiàn)

下面我們將實(shí)現(xiàn)一個(gè)多態(tài)的例子來(lái)結(jié)束本章的內(nèi)容,例子的來(lái)源還是用上面提供的快遞服務(wù)

class Company(object):
    #提供一個(gè)快遞服務(wù)接口
    def express_service(self, express_company):
         express_company.send()

#順風(fēng)快遞公司
class FS(Company):
    def send(self):
        print('welcome to express by FS')

#中通跨地公司
class ZT(Company):
    def send(self):
        print('welcome to express by ZT')

#申通跨地公司
class ST(Company):
    def send(self):
        print('welcome to express by ST')

if __name__ == '__main__':
    service = Company()
    #使用FS快遞服務(wù)
    fs = FS()
    service.express_service(fs)
    #使用ZT快遞服務(wù)
    zt = ZT()
    service.express_service(zt)
    #使用ST快遞服務(wù)
    st = ST()
    service.express_service(st)

各位若是初學(xué)者一定要敲代碼,去執(zhí)行,去體會(huì)一下類(lèi)的三大屬性


note: 初學(xué)者最容易犯的錯(cuò)就是書(shū)面上看著挺簡(jiǎn)單的啊,把書(shū)一關(guān)上就懵了,想要成為一個(gè)程序員,一定要多去敲代碼,切記,切記

歡迎關(guān)注我:「愛(ài)做飯的老謝」,老謝一直在努力...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,699評(píng)論 19 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類(lèi)相關(guān)的語(yǔ)法,內(nèi)部類(lèi)的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線(xiàn)程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,853評(píng)論 18 399
  • 特別說(shuō)明,為便于查閱,文章轉(zhuǎn)自https://github.com/getify/You-Dont-Know-JS...
    殺破狼real閱讀 1,266評(píng)論 0 4
  • 小麥爸爸是個(gè)重情義的人,心里一直惦記著這一家三口,托人四處打聽(tīng)。后來(lái)聽(tīng)說(shuō)他們搬去了S市,在那兒又干起了老本行,種蔬...
    Williamlora閱讀 293評(píng)論 0 0
  • 因?yàn)闂l件限制,結(jié)束作品依然是鉛筆畫(huà)。 臨摹了許久,想著也算是完成了100幅,到最后何不自己創(chuàng)作幾幅?! 可真拿起筆...
    葉聽(tīng)雨閱讀 775評(píng)論 19 17

友情鏈接更多精彩內(nèi)容