寫給小白的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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...