亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

python面向?qū)ο蠡A(chǔ)(三)

系統(tǒng) 1819 0

本節(jié)開始,我們將討論面向?qū)ο缶幊痰娜筇卣鳎悍庋b、繼承和多態(tài)。下面,我們將由簡至難,依次討論封裝、繼承、多態(tài)。

一. 封裝?enclosure

  • 封裝:指隱藏類的實(shí)現(xiàn)細(xì)節(jié),讓使用者不用關(guān)心這些細(xì)節(jié);
  • 目的:讓使用者通過盡可能少的方法(或?qū)傩?操作對象;
  • 如何封裝:通過私有屬性和方法;
  • 私有屬性和方法:
  1. 以雙下劃線'__'開頭,不以雙下劃線結(jié)尾的標(biāo)識(shí)符為私有成員;
  2. 私有成員只能用此類的方法進(jìn)行訪問和修改
  • 擴(kuò)展:了解java的讀者可能知道,java中使用了private、default、protected、public關(guān)鍵字,實(shí)現(xiàn)了更豐富的封裝;
  • 示例:
            
              class A:
    """用私有屬性和私有方法封裝屬性和方法"""
    __dd = 300

    def __init__(self):
        # 創(chuàng)建私有屬性,此屬性在類外無法訪問
        self.__e = 100

    @staticmethod
    # 私有方法
    def __en():
        print('私有方法__en被調(diào)用!')

    @classmethod
    def get__dd(cls):
        print("私有的類變量__dd:{}".format(cls.__dd))

    def info(self):
        print('A的實(shí)例方法info訪問私有屬性__e:', self.__e)
        # 調(diào)用私有方法
        self.__en()


if __name__ == "__main__":
    a = A()
    a.info()
    a.__class__.get__dd()

    # print(a.__e) #AttributeError: 'A' object has no attribute '__e'
    # print(a.__en()) #AttributeError: 'A' object has no attribute '_en'

    # 創(chuàng)建新變量(屬性)
    a.__e = 'hello'
    print(a.__e)
    print(a.__dict__)

            
          

運(yùn)行結(jié)果:

? ? python面向?qū)ο蠡A(chǔ)(三)_第1張圖片

二.?繼承 inheritance 和 派生 derived

  • 什么是繼承/派生:
  1. 繼承是指從已有的類中派生出新的類,新類具有原類的行為,并能擴(kuò)展新的行為;
  2. 派生類就是從一個(gè)已有的類衍生出新的類,在新的類上可以添加新的屬性和行為;
  • 作用:
  1. 用繼承派生機(jī)制,可以將一些共有功能加在基類中,實(shí)現(xiàn)代碼共享;(共有的屬性和方法向上提,形成抽象)
  2. 在不改變超類的代碼基礎(chǔ)上改變原有功能
  • 名詞:
  1. 基類 base class / 超類 super class / 父類 father class
  2. 派生類 derived class / 子類

1. 單繼承

  • 語法:

?? ??? ?class 類名( 基類名 ):
?? ??? ??? ?語句塊

  • 說明:單繼承是派生類由一個(gè)基類衍生而來的
  • 類的__base__屬性:用來記錄此類的父類
  • 子類對象可以當(dāng)成父類對象來使用:

? ? ? ? python面向?qū)ο蠡A(chǔ)(三)_第2張圖片

  • 示例
            
              class Human:
    """此類用來描述人類的共同行為"""
    @staticmethod
    def say(what):
        print('說:', what)

    @staticmethod
    def walk(distance):
        print('走了', distance, '公里')


class Student(Human):
    """描述學(xué)生的共同行為"""
    @staticmethod
    def study(subject):
        print('學(xué)習(xí)', subject)


class Teacher(Student):
    @staticmethod
    def teach(content):
        print('正在教', content)


if __name__ == "__main__":
    h1 = Human()
    h1.say('Today is a good day.')
    h1.walk(5)

    print("#########################")
    s1 = Student()
    s1.say('How are you?')
    s1.walk(5)
    s1.study('Python')

    print("#########################")
    t1 = Teacher()
    t1.say('I am a teacher.')
    t1.walk(3)
    t1.teach('講解繼承派生')
    t1.study('滑冰')

            
          

運(yùn)行結(jié)果:

?? python面向?qū)ο蠡A(chǔ)(三)_第3張圖片

2. 覆蓋 override

  • 概念:覆蓋是指在有繼承關(guān)系的類中,子類中實(shí)現(xiàn)了與父類同名的方法,子類實(shí)例調(diào)用該方法時(shí),實(shí)際調(diào)用的是子類中覆蓋版本的方法,這種現(xiàn)象被稱為覆蓋;
  • super 函數(shù):
  1. super(type, obj):返回綁定超類的實(shí)例(要求obj必須為type類型的實(shí)例);
  2. super():返回綁定超類的實(shí)例,等同于super(__class__,實(shí)例方法的第一個(gè)參數(shù)self);
  3. super()必須放在方法內(nèi)調(diào)用
  4. 作用:返回綁定超類的實(shí)例,用超類的實(shí)例來調(diào)用其父類的覆蓋方法;
  • 顯示調(diào)用父類的構(gòu)造方法:當(dāng)子類中實(shí)現(xiàn)了__init__方法,父類的構(gòu)造方法并不會(huì)被調(diào)用,此時(shí)需要顯示調(diào)用父類的構(gòu)造方法:super().__init__(參數(shù))
  • 示例1:在方法內(nèi)使用super()
            
              class Human:
    def __init__(self, n, a):
        self.name = n
        self.age = a

    def info(self):
        print('name:', self.name)
        print('age:', self.age)


class Student(Human):
    def __init__(self, n, a, s):
        # 顯示調(diào)用父類的初始化方法
        super().__init__(n, a)
        self.score = s

    def info(self):
        """# 覆蓋,子類只負(fù)責(zé)干子類的事情"""
        super().info()
        print('score:', self.score)


if __name__ == "__main__":
    h1 = Human('Alex', 22)
    h1.info()

    s1 = Student('Thomas', 25, 99)
    s1.info()

            
          

示例2:

            
              class A:
    def work(self):
        print('A.work被調(diào)用!')


class B(A):
    """用super構(gòu)造函數(shù)來間接調(diào)用父類的覆蓋版本的方法"""
    def work(self):
        print('B.work被調(diào)用!')

    def super_work(self):
        """此方法先調(diào)用一下子類的方法,再調(diào)用一下父類的方法"""
        self.work()
        # super().work() #調(diào)用父類的work,不能在方法外調(diào)用
        # super(B,self).work()
        super(__class__, self).work()


if __name__ == "__main__":
    a = A()
    a.work()

    print("###################")
    b = B()
    b.work()

    # 方法外部,使用super()函數(shù)調(diào)用B的父類A的work方法
    print("###################")
    super(B, b).work()

    print("###################")
    b.super_work()

            
          

示例2運(yùn)行結(jié)果:

?? python面向?qū)ο蠡A(chǔ)(三)_第4張圖片

2. 多繼承?multiple inheritance

  • 概念:多繼承是指一個(gè)子類繼承自兩個(gè)或兩個(gè)以上的基類;
  • 語法:class類名(基類名1, 基類名2...);
  • 說明:
  1. 一個(gè)子類同時(shí)繼承自多個(gè)父類,父類中的方法可以同時(shí)被繼承下來;
  2. 如果兩個(gè)父類中有同名的方法,則在子類中又沒有覆蓋此方法時(shí),調(diào)用結(jié)果難以確定
  • 問題(缺陷):多繼承可能會(huì)有標(biāo)識(shí)符(名字空間)沖突的問題;
  • 多繼承的MRO(Method Resolution Order)問題:
  1. '類'的__mro__屬性:用來記錄屬性或方法的查找順序;
  2. 示例:
            
              class A:
    def m(self):
        print('A.m()')


class B:
    def m(self):
        print('B.m()')


class C:
    def m(self):
        print('C.m()')


class D(A, B, C):
    def m(self):
        super(A, self).m()
        super(B, self).m()
        super().m()
        print('D.m()')


if __name__ == "__mian__":
    d = D()
    d.m()
    print(D.__mro__)

            
          

運(yùn)行結(jié)果:

結(jié)果分析: super()函數(shù)根據(jù)MRO順序來查找方法

類D同時(shí)繼承自類A,B, C,且這些類中都有方法m,在調(diào)用super時(shí),方法的查找順序是按照D.__mro__屬性指定的順序;在D.m()中首先調(diào)用的是super(A, self).m(),A的上一個(gè)是B,因此首先打印B.m();同理,super(B, self).m(),B的上一個(gè)是C,因此打印C.m()。

3. 用于類的函數(shù):issubclass(cls, class_or_tuple)

  • 判斷一個(gè)類是否繼承自其它的類,如果此類是 class 或 tuple 中的一個(gè)派生子類,則返回 True ,否則返回 False;
  • 一切類型都是 object 的子類

三.?多態(tài) polymorphic

  • 什么是多態(tài):多態(tài)是指在有繼承/派生關(guān)系的類中,調(diào)用“基類對象的方法”,實(shí)際能調(diào)用子類的覆蓋方法,這種現(xiàn)象被稱為多態(tài);
  • 說明:
  1. 多態(tài)“調(diào)用的方法與對象相關(guān)”,不與類型相關(guān);
  2. Python全部對象都只有運(yùn)行時(shí)狀態(tài)(動(dòng)態(tài)),沒有'C++語言'里的編譯時(shí)狀態(tài)(靜態(tài))
  • 示例:
            
              class Shape:
    def draw(self):
        print('Shape的draw()被調(diào)用')


class Point(Shape):
    def draw(self):
        print('正在畫一個(gè)點(diǎn)')


class Circle(Point):
    def draw(self):
        print('正在畫一個(gè)圓')


def my_draw(s):
    """示意多態(tài)的使用"""
    # s.draw調(diào)用誰是在運(yùn)行時(shí)由s的類動(dòng)態(tài)決定
    s.draw()


if __name__ == "__main__":
    my_draw(Shape())
    my_draw(Point())
    my_draw(Circle())

            
          

運(yùn)行結(jié)果:

python面向?qū)ο蠡A(chǔ)(三)_第5張圖片


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 国产欧美日韩图片一区二区 | 四虎影视永久在线精品免费播放 | 久久不卡视频 | 日本不卡视频在线视频观看 | 日韩精品一区二区三区免费观看 | 国产免费久久 | 91精品国产乱码在线观看 | 欧美成人剧情中文字幕 | 日本伊人 | 色狠狠色综合吹潮 | 在线婷婷| 久草青青 | 91中文字幕在线观看 | 日本毛片在线看 | 最近中文2019视频在线 | 妖精视频在线看免费视频 | 久久久免费精品 | 91精品久久久久久久久久小网站 | www国产永久免费视频看看 | 欧美高清理论片在线观看 | 伊人狠狠丁香婷婷综合色 | 欧美成人性色生活片天天看 | 国产欧美久久一区二区 | 午夜国产在线观看 | 国产亚洲精品看片在线观看 | 欧美激情久久欧美激情 | 国产成人免费观看 | 香蕉人人超人人超免费看视频 | 国产a毛片清高视频 | 欧美papa| 一区二区三区无码高清视频 | 最新国产在线 | 五月婷婷在线观看视频 | 四虎影院免费视频 | 亚洲国产成+人+综合 | 精品免费一区二区三区 | 四虎影视免费在线观看 | 五月婷综合网 | 日韩毛片 | 国产一区 在线视频 | 成人免费牛牛在线视频 |