最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python面向?qū)ο笕筇卣鳎豪^承、封裝和多態(tài)的深度解析

 更新時間:2025年01月11日 09:31:08   作者:小劉042  
在面向?qū)ο蟪绦蛟O(shè)計中,對象可以看做是數(shù)據(jù)(特性)以及由一系列可以存取、操作這些數(shù)據(jù)的方法所組成的集合,Python是面向?qū)ο蟮恼Z言,支持面向?qū)ο缶幊痰娜筇匦裕豪^承、封裝(隱藏)、多態(tài),本文將逐一講解Python的三大特性

在面向?qū)ο蟪绦蛟O(shè)計中,對象可以看做是數(shù)據(jù)(特性)以及由一系列可以存取、操作這些數(shù)據(jù)的方法所組成的集合。Python是面向?qū)ο蟮恼Z言,支持面向?qū)ο缶幊痰娜筇匦裕豪^承、封裝(隱藏)、多態(tài),本文將逐一講解Python的三大特性。

封裝

繼承的基本概念以及使用

封裝的概念:隱藏內(nèi)部實現(xiàn)的細節(jié),只對外提供操作方法(接口)。這個概念我們在上一小節(jié)中也已經(jīng)學(xué)習(xí)過了,我們主要是去了解其在代碼中是如何去實現(xiàn)的:通過有著類似 訪問修飾限定符 功能的下劃線來實現(xiàn)。

權(quán)限控制:通過對屬性或方法添加單下劃線、雙下劃線以及首尾雙下劃線來實現(xiàn)。

下劃線種類

功能

單下劃線開頭

表示protected,受保護的成員,這類成員被視為僅供內(nèi)部家族使用,允許類本身和子類進行訪問,但實際上它可以被外部代碼訪問

雙下劃線開頭

表示private,私有的成員,這類成員只允許定義該屬性或方法的類本身進行訪問

首尾雙下劃線

一般表示特殊的方法

代碼演示:

class Dog():
    # 首尾雙線劃線 ——> 特殊方法
    def __init__(self, name, age):
        # 雙下劃線開頭 ——> private修飾,只能在類內(nèi)訪問
        self.__name = name
        # 單下劃線開頭 ——> protected修飾,在類內(nèi)與子類才能訪問
        self._age = age
 
    # 單下劃線開頭 ——> protected修飾,在類內(nèi)與子類才能訪問
    def _fun1(self):
        print('這是被protected所修飾的方法')
    # 雙下劃線開頭 ——> private修飾,在類內(nèi)才能訪問
    def __fun2(self):
        print('這是被private所修飾的方法')
 
# 這里是類外了
dog = Dog('小劉', 18)
print(dog._age)
# print(dog.__name)
dog._fun1()
# dog.__fun2()
# 和上面一樣,直接去訪問的話,就會報錯,
# 但是我們可以使用 對象.__dir()__ 或者 dir(對象) 先去查看所有的屬性與方法
# 然后通過其中的"屬性"與"方法名"去調(diào)用真正的屬性與方法
# print(dog.__dir__())
# print(dir(dog))
 
print(dog._Dog__name)
dog._Dog__fun2()

運行結(jié)果:

Python初始 - 面向?qū)ο笕筇卣鱛下劃線

根據(jù)上面的訪問方式,我們可以推測出:被 protected、private 所修飾 方法 與 屬性只是在類中對應(yīng)的名稱發(fā)生了變化,而我們不知道,但是可以通過特殊手段知曉,從而繼續(xù)訪問。

但是上面的方式不是很推薦,類似與 Java中的反射機制了,有點反常規(guī)。除了上面這種方式,Python還提供了兩種方式來實現(xiàn)訪問 與 修改 私有是屬性與方法。

1、在 私有的方法 或者 屬性上,進行套殼處理。

2、在1的基礎(chǔ)上,通過 @property 裝飾器 來修飾方法,使其變?yōu)閷傩?,就變?yōu)樵L問與修改屬性了,最終也會變的很簡單。

代碼演示:

class Dog():
    def __init__(self, name, age):
        self.__name = name
        self.age = age
 
    # 如果想要去訪問除了,使用dir()之外,還有兩種方式:
 
    # 使用實例方法去間接訪問與修改
    def get_name(self):
        return self.__name
    def set_name(self, name):
        self.__name = name
 
    # 使用@property裝飾器,將方法轉(zhuǎn)為屬性使用
    @property
    def name(self):
        return self.__name
    @name.setter
    def name(self, name):
        self.__name = name
 
dog = Dog('老劉', 8)
# 1、通過實例方法的形式去使用
print(dog.get_name())
dog.set_name('小劉')
print('='*18)
# 2、通過@property裝飾器,將方法轉(zhuǎn)為屬性
print(dog.name)
dog.name = '老劉' # 修改屬性的樣式,去傳參
print(dog._Dog__name)
print('='*18)
dog._Dog__name = '小劉'
print(dog._Dog__name)

運行結(jié)果:

Python初始 - 面向?qū)ο笕筇卣鱛父類_02

注意:我們在使用 @property 裝飾器,將屬性轉(zhuǎn)為方法時,取值的方法,必須被 @property 修飾,而修改值的方法,必須被 @取值方法名. setter修飾。

繼承

繼承的基本概念以及使用

繼承是指一個類(子類、派生類)繼承另一個類(父類、基類)的屬性與方法。

在Python中一個子類可以繼承N多個父類,這是與 Java決然不同的一點。Java屬于單繼承,而Python屬于多繼承,并且每個類都默認繼承自object類。當然,一個子類可以有多個父類,一個父類也可以有多個子類。

語法:

class 類名([父類列表]):

注意:當一個類的父類只有object類時,默認是可以不寫父類的,但是如果一個類有除object類之外的其他類,就需要將這些類全部寫到 () 中,當然這個()在只有繼承object類的情況下,也是可以不寫的,但是建議還是要寫上去。

代碼演示:

# 默認繼承object類,但是這個可以不寫
class Animal(object):
    def __init__(self, name, age, gender,sort):
        self.name = name
        self.age = age
        self.gender = gender
        self.__sort = sort
 
 
class Dog(Animal):
    pass
 
# 子類繼承父類,會將父類中除private修飾的方法與屬性全部拿過來
# 繼承了 __init__方法,以及 name、age、gender屬性
dog = Dog('小黑', 3, '雄', '哈士奇')
print(dog.name)
print(dog.age)
print(dog.gender)
# 同樣需要特殊手段才能訪問到
print(dog._Animal__sort)

運行結(jié)果:

Python初始 - 面向?qū)ο笕筇卣鱛子類_03

注意:我們在實例化一個對象時,會先去調(diào)用構(gòu)造方法(init 方法)給對象的屬性進行初始化賦值,如果一個類沒有構(gòu)造方法,但是由于這個類是默認繼承自object類,因此會調(diào)用object類中默認的 init 方法,但如果這個類繼承了其他類,就會先在其他類中去搜索這個方法,如果有則調(diào)用;反之,則還是去調(diào)用object類的。 而在上面的代碼中,Animal 類是有 init 方法,因此會去調(diào)用Animal 類的。

我們再看看多繼承的代碼:

class Person():
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender
    def show(self):
        print(f'我叫{self.name},今年{self.age},性別是{self.gender}')
 
class Father(Person):
    def __init__(self,name,age,gender):
        # 可以直接調(diào)用父類的初始化方法
        super().__init__(name,age,gender)
        # 下面這種方式是錯誤的
        # super().name = name
        # super().age = age
        # super().gender = gender
        # 下面的方式也行,但是不推薦
        # self.name = name
        # self.age = age
        # self.gender = gender
 
class Mother(Person):
    def __init__(self, name, age, gender):
        # 可以直接調(diào)用父類的初始化方法
        super().__init__(name, age, gender)
        # 下面這種方式是錯誤的
        # super().name = name
        # super().age = age
        # super().gender = gender
        # 下面的方式也行,但是不推薦
        # self.name = name
        # self.age = age
        # self.gender = gender
 
class Son(Father, Mother):
    def __init__(self, name, age, gender):
        # 可以直接調(diào)用父類的初始化方法
        super().__init__(name, age, gender)
        # 下面這種方式是錯誤的
        # super().name = name
        # super().age = age
        # super().gender = gender
        # 下面的方式也行,但是不推薦
        # self.name = name
        # self.age = age
        # self.gender = gender
 
father = Father('張三',25,'男')
mother = Mother('紅粉佳人',28,'女')
son = Son('趙四',29,'男')
 
father.show()
mother.show()
son.show()

運行結(jié)果:

Python初始 - 面向?qū)ο笕筇卣鱛下劃線_04

上面的代碼中,Son類、Mother類、Father類都是繼承自Person類的屬性與方法,它們是公用Person類的屬性與方法。

注意:上述 Son類繼承了多個父類,當我們?nèi)ナ褂?super().init 方法初始化子類對象時,默認是按照父類在Son()中的順序來查找的,這里是Father類定義聲明在前,因此這里調(diào)用的就是 Father 類的 init 方法,如果想要指定某個類的 init 方法的話,就需要使用 類名.init() 方法。例如:

# 這里的self代指當前Son類的實例對象
Mother.__init__(self,name,age,gender) # 可替換Son類中是super.init

方法重寫

當子類繼承父類時,子類就擁有了父類中的 公有成員、方法和受保護的成員、方法。如果我們對父類中有些成員不滿意的話,子類就可以重新定義成員。同理,方法也是如此,但是重新定義方法麻煩了,那有什么辦法呢?方法重寫,即 偷梁換柱,表面上這個方法還是原來的方法,但是其內(nèi)部實現(xiàn)的結(jié)構(gòu)早就發(fā)生變化了。

重寫的要求:方法名必須一樣,至于方法的返回值類型,參數(shù)列表、訪問權(quán)限這些可以不一樣。

代碼演示:

class Animal():
    def __init__(self,name,age):
        self.name = name
        self.age = age
 
    def eat(self):
        print(f'{self.name}正在吃狗糧,看小黑玩飛盤')
 
class Dog(Animal):
    def __init__(self,name,age):
        super().__init__(name,age)
    # 由于Animal類的eat方法只是隨便說在吃啥,并不具體,
    # 但我們想要打印出具體的食物,因此可以重寫(外殼不變,核心變化)
    def eat(self):
        print(f'{self.name}正在玩飛盤~')
 
class Cat(Animal):
    def __init__(self,name,age):
        super().__init__(name,age)
 
dog = Dog('小黑', 2)
# 子類重寫父類的方法之后,父類再去調(diào)用eat方法,就不再是調(diào)用父類的,而是自己的
dog.eat()
 
cat = Cat('小黃', 3)
# 子類沒有重寫父類的eat方法,因此還是去調(diào)用父類的eat方法
cat.eat()

運行結(jié)果:

Python初始 - 面向?qū)ο笕筇卣鱛父類_05

其實,重寫就是在子類中定義了一個與父類重名的方法,只不過因為 Python中語法的檢查不是很嚴格,因此這里就很容易不理解。

在Python中,我們就將重寫看作是子類定義了一個與父類重名的方法即可,在調(diào)用時,如果子類沒有這個方法,那么就是調(diào)用父類的同名方法,如果還沒有就會報錯。但如果子類有這個方法,那么就是直接調(diào)用子類的方法,即使父類有,也不去調(diào)用("地頭蛇原則")。

多態(tài)

多態(tài)的概念以及基本使用

多態(tài)是指多種形態(tài),當去完成某個行為時,不同的對象可能會產(chǎn)生不同的形態(tài)。

例如,我們在類和對象中說的小故事:當劉建明 與 陳永仁 遇到 韓琛 時,兩人打招呼的方式不一樣,這就是不同對象 在 完成同一個行為時,兩者所產(chǎn)生的形態(tài)不同。

再比如,我們每天都會吃早餐,但是不同的人 在 面對這件事情時,所表現(xiàn)出的行為就不一樣,A 可能吃面條,B可能吃包子、餃子,C可能吃大米飯等。

Python中的多態(tài)與Java、C++不同,Python中的多態(tài)只需要滿足有該方法,然后讓不同的對象去調(diào)用即可,而 Java 中的多態(tài)需要滿足三個條件:向上轉(zhuǎn)型(父類引用指向子類對象)、子類重寫父類的方法、向上轉(zhuǎn)型的父類調(diào)用該方法(被重寫的方法),這時就不再是調(diào)用父類的方法,而是調(diào)用子類的方法。但 Python中,只要這兩個類有相同的方法,當兩者賦值給同一個對象時,去調(diào)用同一個方法就會表現(xiàn)出不同的行為。

其實,多態(tài)就是表層對象一樣,內(nèi)部實際的對象不一樣,那么在調(diào)用同一個方法時,雖然看似是這個表層的對象所調(diào)用的,但實際是內(nèi)部的對象所調(diào)用并執(zhí)行的。

代碼演示:

class Animal():
    def eat(self):
        print('在玩飛盤')


class Person():
    def eat(self):
        print('到處溜達')


class Dog():
    def eat(self):
        print('瘋狂奔跑')


class Cat():
    def eat(self):
        print('偷吃罐頭')


# 定義一個函數(shù),傳入obj對象,并調(diào)用該對象的eat方法
def eat(obj):
    obj.eat()


# 方法得通過類或者對象去"."調(diào)用,而函數(shù)是直接傳參調(diào)用,不要弄混了
eat(Animal())  # 這里需要傳入對象,即:類名()
eat(Person())
eat(Dog())
eat(Cat())

運行結(jié)果:

Python初始 - 面向?qū)ο笕筇卣鱛父類_06

總結(jié)

到此這篇關(guān)于Python面向?qū)ο笕筇卣鳎豪^承、封裝(隱藏)、多態(tài)的文章就介紹到這了,更多相關(guān)Python面向?qū)ο笕筇卣鲀?nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 對python 中re.sub,replace(),strip()的區(qū)別詳解

    對python 中re.sub,replace(),strip()的區(qū)別詳解

    今天小編就為大家分享一篇對python 中re.sub,replace(),strip()的區(qū)別詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • Python面向?qū)ο缶幊讨嘘P(guān)于類和方法的學(xué)習(xí)筆記

    Python面向?qū)ο缶幊讨嘘P(guān)于類和方法的學(xué)習(xí)筆記

    類與類方法是面向?qū)ο蟮木幊陶Z言中必不可少的特性,本文總結(jié)了Python面向?qū)ο缶幊讨嘘P(guān)于類和方法的學(xué)習(xí)筆記,需要的朋友可以參考下
    2016-06-06
  • python實現(xiàn)密碼強度校驗

    python實現(xiàn)密碼強度校驗

    這篇文章主要為大家詳細介紹了python實現(xiàn)密碼強度校驗,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • 用Python實現(xiàn)最速下降法求極值的方法

    用Python實現(xiàn)最速下降法求極值的方法

    今天小編就為大家分享一篇用Python實現(xiàn)最速下降法求極值的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • 對TensorFlow的assign賦值用法詳解

    對TensorFlow的assign賦值用法詳解

    今天小編就為大家分享一篇對TensorFlow的assign賦值用法詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • 淺談Python中的全局鎖(GIL)問題

    淺談Python中的全局鎖(GIL)問題

    今天小編就為大家分享一篇淺談Python中的全局鎖(GIL)問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • 超詳細注釋之OpenCV制作圖像Mask

    超詳細注釋之OpenCV制作圖像Mask

    這篇文章主要介紹了OpenCV制作圖像Mask,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • Python數(shù)據(jù)可視化詳解

    Python數(shù)據(jù)可視化詳解

    數(shù)據(jù)可視化是一種將龐雜抽象的數(shù)據(jù)轉(zhuǎn)化為直觀易懂的圖形的數(shù)據(jù)呈現(xiàn)技術(shù),它能幫助我們快速把握數(shù)據(jù)的分布和規(guī)律,更加輕松地理解和探索信息,本文通過代碼圖片詳細介紹了Python數(shù)據(jù)可視化,感興趣的小伙伴可以參考閱讀
    2023-04-04
  • Android分包MultiDex策略詳解

    Android分包MultiDex策略詳解

    這篇文章主要介紹了Android分包MultiDex策略詳解,具有一定參考價值,需要的朋友可以了解下。
    2017-10-10
  • 使用Pytorch實現(xiàn)two-head(多輸出)模型的操作

    使用Pytorch實現(xiàn)two-head(多輸出)模型的操作

    這篇文章主要介紹了使用Pytorch實現(xiàn)two-head(多輸出)模型的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-05-05

最新評論

额尔古纳市| 延安市| 仙居县| 湟中县| 南投县| 玉龙| 杭锦旗| 潮安县| 石台县| 永胜县| 郧西县| 绥棱县| 若尔盖县| 蒙城县| 凤山县| 霍州市| 安平县| 西昌市| 东乡族自治县| 寿阳县| 太原市| 甘南县| 贡嘎县| 饶平县| 博野县| 云霄县| 镇雄县| 长海县| 蚌埠市| 旬邑县| 麻城市| 珠海市| 辉县市| 孟州市| 图们市| 博白县| 美姑县| 彩票| 高阳县| 五原县| 淄博市|