寫給小白的Python之017:面向對象-封裝、繼承、多態

来源:https://www.cnblogs.com/salmond/archive/2018/05/11/9001257.html
-Advertisement-
Play Games

1. 封裝 面向對象三大特性:封裝、繼承、多態 封裝(Encapsulation):這是定義類的 準則,單個類。根據 職責 將 屬性 和 方法 封裝 到一個抽象的 類 中。 封裝的意義: 1.將屬性和方法放到一起做為一個整體,然後通過實例化對象來處理; 2.隱藏內部實現細節,只需要和對象及其屬性和方 ...


 

1. 封裝

面向對象三大特性:封裝、繼承、多態

封裝(Encapsulation)這是定義類的 準則,單個類。根據 職責 將 屬性 和 方法 封裝 到一個抽象的 類 中。

封裝的意義:

1.將屬性和方法放到一起做為一個整體,然後通過實例化對象來處理;

2.隱藏內部實現細節,只需要和對象及其屬性和方法交互就可以了;

3.對類的屬性和方法增加 訪問許可權控制。

 

2. 繼承

繼承:這是設計類的 技巧,父與子。

  • 主要體現是實現代碼的 重用,相同的代碼不需要重覆的編寫;
  • 子類可以在父類功能上進行重寫,擴展類的功能。

在面向對象編程中,當我們已經創建了一個類,而又想再創建一個與之相似的類,比如添加幾個方法,或者修改原來的方法,這時我們不必從頭開始,可以從原來的類派生出一個新的類, 我們把原來的類稱為父類或基類,而派生出的類稱為子類或派生類,子類繼承了父類的所有數據和方法。

從技術上說, OOP里繼承最主要的用途是實現多態。對於多態而言,重要的是介面繼承性,屬性和行為是否存在繼承性,這是不一定的。事實上, 大量工程實踐表明,重度的行為繼承會導致系統過度複雜和臃腫,反而會降低靈活性。因此現在比較提倡的是基於介面的輕度繼承理念。這種模型里因為父類(介面類)完全沒有代碼,因此根本談不上什麼代碼復用。

2.1 單繼承

子類的定義如下:

class 子類名(父類名):

    <statement-1>

    ...

    <statement-N>

父類名 BaseClassName 對於子類來說必須是可見的。也可以繼承在其他模塊中定義的父類:

class 子類名(模塊名.父類名):

對於子類的屬性引用:首先會在當前的子類中搜索,如果沒有找到,則會遞歸地去父類中尋找。

從C++術語上講,Python 類中所有的方法都是 vitual 的,所以子類可以覆寫(override)父類的方法。在子類中一個覆寫的方法可能需要調用父類的方法,可以通過以下方式:

父類名.方法(self, arguments)

 

2.2 多繼承

Python支持多繼承,一個多繼承的定義形如:

class 子類名(父類名1, 父類名2, 父類名3):

多個父類有同名屬性和方法

子類的魔法屬性__mro__決定了屬性和方法的查找順序。如果多個父類中有同名的 屬性和方法,則預設使用第一個父類的屬性和方法(根據類的魔法屬性mro的順序來查找)

子類重寫父類的屬性和方法

子類和父類的方法名和屬性名相同,則預設使用子類的,叫 子類重寫父類的同名方法和屬性。

使用重寫的目的:當子類發現父類的大部分功能都能滿足需求,但是有一些功能不滿足,則子類可以重寫父類方法。

2.3 調用父類方法

重寫之後,如果發現仍然需要父類方法,則可以強制調用父類方法。

方法1. 指定執行父類的方法

無論何時何地,self都表示是子類的對象。在調用父類方法時,通過傳遞self參數,來控制方法和屬性的訪問修改。通常用於多繼承。

  • 父類名.父類方法(self, 參數列表)
  • 父類名().屬性/方法   # 不推薦這樣訪問父類的實例屬性,相當於創建了一個新的父類對象

子類繼承了多個父類,如果父類類名修改了,那麼子類也要涉及多次修改。而且需要重覆寫多次調用,顯得代碼臃腫。

方法2. super() 帶參數版本

只支持新式類,支持Python2和3。工作中使用這個。

  • super(子類名, self).父類方法(參數列表)

# super(子類名, self).__init__() # 執行父類的 __init__方法

# self.方法名()

示例:

class Animal:

    def __init__(self, age):  # 1.父類有時候需要接收一些參數
        self.age = age


class Cat(Animal):

    def __init__(self, age):  # 3.一般情況下,父類需要的參數,子類也是動態來獲取
        self.name = '伊麗莎白'
        super(Cat, self).__init__(age)  # 2.子類需要為父類傳遞實參


cat = Cat(12)  # 4. 根據子類需求,傳遞對應的實參
print(cat.age)  # 12

方法3. super()的簡化版

只支持新式類,只支持Python3

  • super().父類方法(參數列表)  # 執行父類的 實例方法

super().__init__()  # 執行父類的 __init__方法

 

知識點:

  • 使用super() 可以逐一調用所有的父類方法,並且只執行一次。調用順序遵循 mro 類屬性的順序。
  • 註意:如果繼承了多個父類,且父類都有同名方法,則預設只執行第一個父類的(同名方法只執行一次,目前super()不支持執行多個父類的同名方法)
  • super() 在Python2.3之後才有的機制,用於通常單繼承的多層繼承。

3. 多態

多態是指對不同類型的變數進行相同的操作,它會根據對象(或類)類型的不同而表現出不同的行為。即 不同類的對象調用相同方法,產生不同的結果。

多態(Polymorphism):

  • 不同的子類對象調用相同的父類方法,產生不同的 執行結果;父類能工作的地方,子類都能工作;
  • 多態以繼承和重寫父類方法為前提;
  • 多態是調用方法的技巧,不會影響到類的內部設計。

多態的好處:

在保證安全性的前提下,提高了方法調用的靈活性。

多態的實現:

1.定義一個父類

2.定義多個子類,並重寫父類的方法

3.傳遞子類對象給調用者,不同子類對象能產生不同執行效果

示例:

class Dog(object):
    def work(self):  # 父類提供統一的方法,哪怕是空方法
        pass

class ArmyDog(Dog):   # 繼承 Dog
    def work(self):  # 子類重寫方法,並且處理自己的行為
        print('追擊敵人')

class DrugDog(Dog):
    def work(self):
        print('追查毒品')

class Person(object):
    def work_with_dog(self, dog):
        dog.work()    # 使用小狗可以根據對象的不同而產生不同的運行效果, 保障了代碼的穩定性
 

# 子類對象可以當作父類來使用
dog = Dog()
print(isinstance(dog, Dog))  # True

ad = ArmyDog()
print(isinstance(ad, Dog))  # True

dd = DrugDog()
print(isinstance(dd, Dog))  # True

p = Person()
p.work_with_dog(dog)
p.work_with_dog(ad)  # 同一個方法,只要是 Dog 的子類就可以傳遞,提供了代碼的靈活性
p.work_with_dog(dd)  # 並且傳遞不同對象,最終 work_with_dog 產生了不同的執行效果

# 最終效果
# Person 類中只需要調用 Dog 對象 work() 方法,而不關心具體是 什麼狗
# work() 方法是在 Dog 父類中定義的,子類重寫並處理不同方式的實現
# 在程式執行時,傳入不同的 Dog 對象作為實參,就會產生不同的執行效果

多態總結:

# 定義:多態是一種使用對象的方式,子類重寫父類方法,調用不同子類對象的相同父類方法,可以產生不同的執行結果。

# 好處:調用靈活,有了多態,更容易編寫出通用的代碼,做出通用的編程,以適應需求的不斷變化!

鴨子類型:

動態語言的“鴨子類型”(duck typeing),它並不要求嚴格的繼承體系,一個對象只要“看起來像鴨子,走起路來像鴨子”,那它就可以被看做是鴨子。即只要一個對象相似的屬性和方法。

動態語言的鴨子類型特點決定了繼承不像靜態語言那樣是必須的。

類型檢查是毀掉多態的利器, 比如type、 isinstance以及isubclass函數,所以,一定要慎用這些類型檢查函數。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • JSPs /admin/* BASIC ...
  • 單體應用架構 架構總感覺理我很遠,有時候感覺很迷茫。今天起我把我認識到的三種架構寫出來,一是希望沉澱一下自己所學的東西,二是希望有人能指出我的不足指出,向大家學習。 第一篇 單體應用架構我會總結出單體架構的優缺點,和一般我在經歷過的項目中單體架構所用到的技術,以及我需掌握的知識。 第二篇 垂直應用架 ...
  • 課程是按照真實企業級開發項目流程進行講解,通過學習此課程可以體會到真實的大型大數據項目開發流程,學完此課程可以熟練掌握大數據技術,java web技術,docker虛擬化技術,分散式技術,緩存技術,linux等。 ...
  • 雙擊 勾上藍色保存 ...
  • 驗證客戶端鏈接的合法性 如果你想在分散式系統中實現一個簡單的客戶端鏈接認證功能,又不像SSL那麼複雜, 那麼可以利用hmac+加鹽的方式來實現。 SocketServer是標準庫中的一個高級模塊(python3.x中重命名為socketserver), 它的目標是簡化很多樣板代碼,它們是創建網路客... ...
  • Java開源生鮮電商平臺-商品表的設計(源碼可下載) 任何一個電商,無論是B2C還是B2B的電商,商品表的設計關係到整個系統架構的核心。 1. 商品基本信息表:用單詞:goods做為商品表 2. 商品分類信息表: 說明:商品分類信息表存在父子級關係,採用parent_id來做父類,預設是0表示頂級。 ...
  • ref:https://www.cnblogs.com/dongguacai/p/6030187.html http://www.360doc.com/content/15/0511/14/12726874_469670444.shtml https://blog.csdn.net/honghail ...
  • 在前面的文章,我提到過VSCO Cam 的膠片濾鏡演算法實現是3d lut。 那麼3d lut 到底是個什麼東西呢? 或者說它是用來做什麼的? 長話短說,3d lut(全稱 : 3D Lookup table )它是通過建立一個顏色映射表,對圖像的色調進行重調的演算法。 有用於攝像機的效果美化潤色,例如 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...