組合,封裝,多態

来源:https://www.cnblogs.com/setcreed/archive/2019/10/11/11656979.html
-Advertisement-
Play Games

[TOC] 組合 什麼是組合 組合指的是一個對象中的屬性,是另一個對象 為什麼要使用組合 減少代碼冗餘 如何使用組合 繼承實現: 組合實現: 總結: 繼承是類與類的關係,一種什麼是什麼的關係,子類與父類是一種從屬關係 組合是對象與對象的關係,一種什麼有什麼的關係,一個對象擁有另一個對象 組合練習 封 ...


[TOC]

組合

什麼是組合

組合指的是一個對象中的屬性,是另一個對象

為什麼要使用組合

減少代碼冗餘

如何使用組合

繼承實現:

# 選課系統:老師類,學生類,老師與學生都有名字、年齡、性別

class People:
    def __init__(self, name, age, sex, year, month, day):
        self.name = name
        self.age = age
        self.sex = sex
        self.year = year
        self.month = month
        self.day = day

    def tell_birth(self):
        print(f'''
        === 出生年月日 ===
        年: {self.year}
        月: {self.month}
        日: {self.day}
        ''')


class Teacher(People):
    def __init__(self, name, age, sex, year, month, day):
        super().__init__(name, age, sex, year, month, day)


class Student(People):
    def __init__(self, name, age, sex, year, month, day):
        super().__init__(name, age, sex, year, month, day)


tea1 = Teacher('tank', 18, 'male', 2001, 1, 1)
tea1.tell_birth()

組合實現:

class People:
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex


class Teacher(People):
    def __init__(self, name, age, sex):
        super().__init__(name, age, sex)

class Student(People):
    def __init__(self, name, age, sex):
        super().__init__(name, age, sex)


class Date:
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    def tell_birth(self):
        print(f'''
        === 出生年月日 ===
        年: {self.year}
        月: {self.month}
        日: {self.day}
        ''')


tea1 = Teacher('tank', 18, 'male')
date_obj = Date(2001, 1, 1)
# 將date對象賦值給tea1對象的屬性date中
tea1.date = date_obj
tea1.date.tell_birth()

總結:

  • 繼承是類與類的關係,一種什麼是什麼的關係,子類與父類是一種從屬關係
  • 組合是對象與對象的關係,一種什麼有什麼的關係,一個對象擁有另一個對象

組合練習

'''
選課系統需求:
    1.學生類,老師類, 學生和老師都有課程屬性, 每一門課程都是一個對象.
        課程: 課程名字,課程周期,課程價錢

    2.學生和老師都有選擇課程的功能, 還有列印所有課程的功能.
'''


class People:
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    def add_course(self, course_obj):
        self.course_list.append(course_obj)

    def tell_all_course(self):
        # 拿到當前對象的課程列表,列表中存放的是一個個對象
        for course_obj in self.course_list:
            # 每一個課程對象查看課程信息的方法
            course_obj.tell_course_info()


class Teacher(People):
    def __init__(self, name, age, sex):
        super().__init__(name, age, sex)
        self.course_list = []


class Student(People):
    def __init__(self, name, age, sex):
        super().__init__(name, age, sex)
        self.course_list = []


class Course:
    def __init__(self, course_name, course_period, course_price):
        self.course_name = course_name
        self.course_period = course_period
        self.course_price = course_price

    def tell_course_info(self):
        print(f'''
        課程名稱:{self.course_name}
        課程周期:{self.course_period}
        課程價格:{self.course_price}
        ''')

tea1 = Teacher('tank', 18, 'male')
stu1 = Student('小明', 18, 'male')

python_obj = Course('python', 6, 2)
linux_obj = Course('linux', 6, 1)

tea1.add_course(python_obj)
tea1.add_course(linux_obj)

tea1.tell_all_course()

封裝

什麼是封裝

封裝指的是把一堆屬性封裝到一個對象中

存數據的目的是為了取,對象可以"."的方式,獲取屬性

為什麼要封裝

封裝的目的是為了方便存取,可以通過對象.屬性的方式獲取屬性

如何封裝

特征:變數 ---> 數據屬性

技能:函數 ---> 方法屬性

在類內部,定義一堆屬性(特征與技能)

訪問限制機制

什麼是訪問限制機制

在類內部定義,凡是以__開頭的數據屬性與方法屬性,都會被python內部隱藏起來,讓外部不能直接訪問內部的__開頭的屬性,如:__name = '小in'

訪問限制機制的目的

一堆隱私的屬性與不能被外部輕易訪問的屬性,可以隱藏起來,不能被外部直接調用

好處:對重要數據獲取的邏輯更加嚴謹,進而保護了數據的安全

隱私屬性可以通過封裝一個介面,在介面內做業務邏輯的處理,再把數據返回給調用者

class Foo:
    # 數據屬性
    __name = 'tank'

    # 方法屬性
    def __run(self):
        print('running...')

    def get_name(self):
        return self.__name

    def set_name(self):
        self.__name = 'cwz'

foo = Foo()
# print(foo.__name)
foo.set_name()
print(foo.get_name())

print(foo._Foo__name)  # _類名__屬性名

註意:在python中,不會強制限制屬性的訪問,類內部__開頭的屬性,只是做了一種變形。若想直接訪問,調用變形後的名字即可

class Teacher:
    def __init__(self, name, age, sex):
        self.__name = name
        self.__age = age
        self.__sex = sex

    # 介面:列印用戶信息介面
    def get_info(self):
        user = input('user:').strip()
        pwd = input('pwd:').strip()
        if user == 'tank' and pwd == '123':

            print(f'''
                姓名:{self.__name}
                年齡:{self.__age}
                性別:{self.__sex}
                ''')

    # 介面:修改用戶信息介面
    def set_info(self, name, age, sex):
        if not isinstance(name, str):
            raise TypeError('名字必須要使用字元串')

        if not isinstance(age, int):
            raise TypeError('年齡必須要使用數字')

        if not isinstance(sex, str):
            raise TypeError('性別必須要使用字元串')

        self.__name = name
        self.__age = age
        self.__sex = sex

t1 = Teacher('tank', 18, 'male')
t1.get_info()
class ATM:
    # 插卡
    def __insert_card(self):
        print('開始插卡')

    # 輸入密碼
    def __input_pwd(self):
        print('開始輸入密碼')

    # 輸入取款金額
    def __input_money(self):
        print('輸入取款金額')

    # 開始吐錢
    def __get_money(self):
        print('開始吐錢')

    # 列印賬單
    def __print_flow(self):
        print('列印賬單')

    # 取錢介面
    def withdraw(self):
        self.__insert_card()
        self.__input_pwd()
        self.__input_money()
        self.__get_money()
        self.__print_flow()
        print('程式執行完畢')

atm = ATM()
atm.withdraw()

property

什麼是property

python內置的裝飾器,主要是給類內部的方法使用

為什麼要用property

使用它的目的,是將類內部的方法(def 方法名() 變成了(def 方法))

在對象使用某個方法時,將對象.方法()變成了對象.方法

如何使用property


'''
計算人的bmi:bmi值 = 體重 / (身高 * 身高)
'''

class People:
    def __init__(self, name, weight, height):
        self.name = name
        self.weight = weight
        self.height = height

    @property
    def bmi(self):
        return self.weight / (self.height ** 2)

p = People('cwz', 180, 1.8)
print(p.bmi)

註意:不能對被裝飾過的方法屬性修改

但是也可以修改(瞭解)

class People:
    def __init__(self, name, weight, height):
        self.name = name
        self.weight = weight
        self.height = height

    @property
    def bmi(self):
        return self.weight / (self.height ** 2)

    @property
    def get_name(self):
        return self.name

    # 修改
    @get_name.setter
    def set_name(self, val):
        self.name = val

    # 刪除
    @get_name.deleter
    def del_name(self):
        del self.name


p = People('cwz', 180, 1.8)
# print(p.bmi)

p.set_name = 'nick'
# print(p.get_name)

del p.del_name

# print(p.get_name)

多態

什麼是多態

多態指的是同一種事物的多種形態

多態的目的

多態也稱之為多態性,在程式中繼承就是多態的表現形式

多態的目的是為了,讓多種不同類型的對象,在使用相同功能的情況下,調用同一個名字的方法名

父類:定義一套統一的標準

子類:遵循父類統一的標準

多態的最終目的:統一子類編寫的規範,為了讓使用者更方便調用相同方法的功能

如何實現:

繼承

抽象類

在python中,不會強制要求子類必須遵循父類的一套標準,所以出現了抽象類

abc模塊

會強制子類遵循父類的一套標準

import abc


class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def eat(self):
        pass

    @abc.abstractmethod
    def drink(self):
        pass

    @abc.abstractmethod
    def speak(self):
        pass


class Pig(Animal):
    def eat(self):
        pass

    def drink(self):
        pass

    def jiao(self):    # 強制使用與父類相同的標準,這樣會報錯
        print('哼哼哼。。。')


pig = Pig()
pig.jiao()

鴨子類型

在不知道當前對象是什麼的情況下,但你長得像鴨子,那麼你就是鴨子類型

在python中,不推薦使用抽象類強制子類的定義,但是推薦子類都遵循鴨子類型

  • 繼承:耦合性太高,程式的可擴展性差
  • 鴨子類型:耦合度第,程式的可擴展性強

多態炫技操作

class Animal:
    def eat(self):
        pass

    def drink(self):
        pass

    def speak(self):
        pass


class Pig(Animal):
    def eat(self):
        pass

    def drink(self):
        pass

    def speak(self):
        print('哼哼哼。。。')


class Cat(Animal):
    def eat(self):
        pass

    def drink(self):
        pass

    def speak(self):
        print('喵喵喵。。。')


class Dog(Animal):
    def eat(self):
        pass

    def drink(self):
        pass

    def speak(self):
        print('汪汪汪。。。')


pig = Pig()
dog = Dog()
cat = Cat()


def BARK(animal):
    animal.speak()


BARK(dog)
BARK(pig)
BARK(cat)

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

-Advertisement-
Play Games
更多相關文章
  • #include<stdio.h>int main(){ double i; double bonus1,bonus2,bonus4,bonus6,bonus10,bonus; printf("你的利潤是:\n"); scanf("%lf",&i); bonus1=100000*0.1; bonus ...
  • Thymeleaf中有許多內置對象,可以在模板中實現各種功能。 下麵有幾個基本對象。 Web對象常用有:request、session、servletContext。 Thymeleaf提供了幾個內置變數param、session、application,分別可以訪問請求參數、session屬... ...
  • 手工操作 —— 穿孔卡片 1946年第一臺電腦誕生--20世紀50年代中期,電腦工作還在採用手工操作方式。此時還沒有操作系統的概念。 程式員將對應於程式和數據的已穿孔的紙帶(或卡片)裝入輸入機,然後啟動輸入機把程式和數據輸入電腦記憶體,接著通過控制台開關啟動程式針對數據運行;計算完畢,印表機輸出 ...
  • 一、基本介紹 logging 模塊是python自帶的一個包,因此在使用的時候,不必安裝,只需要import即可。 logging有 5 個不同層次的日誌級別,可以將給定的 logger 配置為這些級別: DEBUG:詳細信息,用於診斷問題。Value=10。 INFO:確認代碼運行正常。Value ...
  • 1. 多線程 如果有多個線程在同時運行,而這些線程可能會同時運行這段代碼。程式每次運行結果和單線程運行的結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是線程安全的。 我們通過一個案例,演示線程的安全問題: 電影院要賣票,我們模擬電影院的賣票過程。假設要播放的電影是 “功夫熊貓3”,本次電影的 ...
  • 線程 什麼是線程 官方定義: 線程(thread)是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以併發多個線程,每條線程並行執行不同的任務。 說人話: 假如 進程 是保潔公司, 線程 就是公司的員工。當公司接到 ...
  • 1. 多線程 1.1 多線程介紹 學習多線程之前,我們先要瞭解幾個關於多線程有關的概念。 進程:進程指正在運行的程式。確切的來說,當一個程式進入記憶體運行,即變成一個進程,進程是處於運行過程中的程式,並且具有一定獨立功能。 線程:線程是進程中的一個執行單元,負責當前進程中程式的執行,一個進程中至少有一 ...
  • 區分環境的配置 properties 配置 yml 配置 區分環境的代碼 修飾類 修飾註解 修飾方法 激活 profile 插件激活 profile main 方法激活 profile jar 激活 profile 在 Java 代碼中激活 profile ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...