第六章:面向對象

第一節:關於類

面向對象

  • 面向對象

之前我們介紹過函數,函數是對程序語句的封裝與複用;
類是則是對 變量函數 的封裝和複用,封裝有機關聯的變量和函數爲類,變量和函數,稱爲 類的屬性方法
由於類比函數的封裝又提高了一個層次,因此複用性也得到進一步提升;(試想一下維護100個函數直觀容易,還是維護5個類直觀容易呢?)
面向過程的編程是以 函數 爲核心的,而面向對象的編程是以 爲核心的,一切功能的實現,都是通過創建一個司職該功能的類的實例,進而調用其方法去予以實現的;
以類爲核心的、面向對象的編程,提高了代碼的模塊化程度,便於大規模協作的開展;
在面向對象的程序開發(Object-Oriented-Programming或OOP)中,架構師的工作,往往只是模塊拆分、接口定義、實例組裝,類內部的具體方法接口的實現,則交由其他人去完成;
現如今的高級語言,基本都是面向對象的;
面向對象的三大特性: 封裝繼承多態
另一種提法是四大特性,即三大特性的基礎上,再加上一個 抽象

  • 封裝

    封裝就是將常用的代碼段封裝爲函數,常用的函數封裝爲類,常用的類封裝爲模塊與類庫;
    封裝提高了代碼的可維護性和複用性,同時也更利於開源與傳播;
    封裝性催生了模塊化,便於大規模協作開發的開展;

  • 繼承

    正如自然界中,動物=>人=>程序員的關係,人是動物類的一個分支,程序員是人的一個分支,在編程中,我們可以通過繼承來表達這樣的關係;
    動物類是人類的父類(又叫超類),人是程序員的父類;
    動物類的共同特徵,如都有生命、都會新陳代謝、都會死亡等等,在定義人這個類時,是無需重複聲明的,這樣就在一層層的繼承中,節省了大量的代碼;
    有繼承就有發展,否則繼承就沒有意義;

    【編程中的繼承】
    在編程中,發展體現爲:
    ①在父類的基礎上增加新的屬性與方法;
    ②重寫(或者叫覆寫、覆蓋)父類方法;
    對父類方法的覆寫,又可以分爲【顛覆式】和【改良式】兩種;
    【顛覆式】覆寫是指子類全盤否定父類方法實現,由子類自己做一個全新的實現;
    【改良式】覆寫是指子類先將父類的實現拿過來,再進行新的拓展;

  • 多態

在繼承的基礎上,一個父類會有不同的子類實現,如戰士父類可以有騎兵、步兵、弓弩手等不同子類;
多態,即【一個父類可以有多種不同的子類形態】;

【多態的共性與個性】
在多態中,同源子類之間,既存在共性,又存在個性,共性與個性各有其用處;
例如騎兵、步兵、弓弩手都是戰士的子類,因此他們都有進攻方法與防守方法,這就是【共性】;
而他們的具體進攻方法各自有不同的實現,騎兵衝鋒、步兵肉搏、弓弩手射箭,這就是【個性】;
在一支由不同兵種組成的軍隊中(即戰士實例的集合),當總司令下達全體進攻的命令時,不同兵種做何種具體形式的進攻(個性)是不重要的,重要的是共性;
當司令想要採用一些細膩的戰術時,比如先進行一輪齊射,再由騎兵進行一輪踩踏,最後上步兵打掃戰場,此時不同兵種的差異化進攻方式則展現其價值,此時個性變得重要;
共性是由父類所帶來的,個性是由子類覆寫所帶來的;

  • 抽象

    在繼承和多態中,如果父類不對某個方法做任何實現,只是留白,具體的實現交由子類自己去完成,這時我們稱該方法是抽象的;
    如果一個父類中的所有方法都是抽象的,我們就稱該類爲一個【接口】;
    抽象是一種藝術,架構師就是這種藝術的玩弄者;
    架構師所做的工作,就是拆分模塊,定義接口,完成預組裝,形成一具沒有血肉的架,然後將填充的工作下放到團隊中的不同程序員,填充完成之日即是項目大廈落成之時;

類的封裝

例:

  • 封裝一個人的類Person,需求如下:

    1、封裝以下屬性:姓名、年齡、存款
    2、封裝自我介紹方法,陳述以上屬性
    3、創建一個人,設置其基本信息
    4、打印此人信息
    5、令此人進行自我介紹

# 封裝一個Person類,將與人有關的屬性、方法組合在一起,以便將來複用
class Person:
    # 屬性定義和默認值
    name = "林阿華"
    age = 20
    rmb = 50

    # 構造方法:外界創建類的實例時會調用
    # 構造方法是初始化實例屬性的最佳時機
    def __init__(self,name,age,rmb):
        print("__init__的方法被調用了")
        self.name = name
        self.age = age
        self.rmb = rmb

    # 自我介紹方法
    #  self = 類的實例
    def tell(self):
        print("我是%s,我%d歲了,我有存款%.2f萬元"%(self.name,self.age,self.rmb))
  • 創建實例p,並調用Person的tell()方法
# 創建Person類的實例
p = Person("易阿天",60,500)

# 調用實例的tell方法
p.tell()

執行結果:
在這裏插入圖片描述

注意將Person的屬性和方法使用一個 標準制表符 縮進在Person的類定義以內;
“_ init _” 是類的構造方法,用於創建類的實例,左右各有兩個下劃線;
使用PyCharm輸入完def __init時系統彈出提示,IDE會自動完成方法的定義;
每個方法在定義時,系統會自動加上一個 self 參數在第一個參數位,這個參數代表將來創建的實例本身;
再調用方法時, self 是不必親自傳入的,self是系統用來標識實例本身的;
構造方法的調用形式爲: Person(self以外的其它參數)

類的私有成員

【成員】就是指類的屬性方法
【私有】,即不能再類的外界進行訪問;
目的是爲了 保障安全 ,如涉及隱私的屬性、核心方法實現等;

例:

  • 封裝一個人的類Person,需求如下:
    1、創建一個Person類,添加存款信息
    2、保護存款信息,將其設置爲私有
    3、爲存款信息添加保護,使其不能被直接訪問
    4、增加設置密碼功能 ·增加存款查詢功能
    5、只有輸入密碼正確的情況下才能查詢存款信息
class Person:
    # 普通屬性與私有屬性
    name = "林阿華"
    age = 20
    __rmb = 1000  #(須通過公有方法來訪問)

    #  私有方法:設置存款
    def __setrmb(self,rmb):
        self.__rmb = rmb

    #  通過普通方法訪問私有方法進行存款設置
    def setrmb(self,rmb):
        pwd = input("請輸入設置密碼:")
        if (pwd == "123456"):
            self.__setrmb(rmb)
        else:
            print("您沒有權限")

    #  公開一個普通方法,共外界訪問私有屬性self.__rmb
    def getrmb(self):
        pwd = input("請輸入查詢密碼:")
        if (pwd == "123456"):
            return self.__rmb
        else:
            return "您沒有訪問權限"

    #  普通方法
    def tell(self):
        print("大家好,我是%s"%(self.name))
  • 創建Person實例,並通過公有方法訪問私有成員
p = Person()

#通過實例訪問類的普通屬性
print(p.name)
print(p.age)

# 私有成員不能被直接訪問
#  print(p.__rmb)        # AttributeError: 'Person' object has no attribute '__rmb'


#通過實例訪問類的普通方法
p.tell()

#通過普通方法訪問私有屬性
rmb = p.getrmb()
print("我的存款是:",rmb)

# 通過普通方法訪問私有方法
p.setrmb(500)
rmb = p.getrmb()
print("我的存款是:",rmb)

執行結果:
在這裏插入圖片描述- 注意的幾個問題
1、代碼中的__rmb屬性、__setrmb方法都是私有的,在類的外部是無法p.__rmb進行直接訪問的;
2、任何前置兩個下劃線的成員(屬性與方法)都是私有的,只能在類的內部進行訪問;
外界訪問私有成員的方法是,使用公有方法對外界提供私有成員訪問接口,但在內部先行進行權限校驗,如輸入密碼等,如本例中的setrmb方法和getrmb方法;

類的繼承與多繼承

類的專有方法

類的多態

靜態方法和類方法

第二節:裝飾器

私有屬性訪問器

property裝飾器

無參裝飾器

帶參裝飾器

使用類定義裝飾器

例:時間統計裝飾器

第三節:模塊和類庫

==使用系統標準庫 ==

==安裝和使用第三方庫 ==

==使用自己寫的類庫 ==

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章