面向對象--封裝 多態
阿新 • • 發佈:2019-02-20
view pri 一個 prop 參數 -c 界面 note @property
封裝 字面意思 把什麽東西裝到容器在封閉起來
與隱藏有相似意思 不是單純的隱藏
官方解釋:對外部隱藏實現細節,並提供簡單的使用接口
封裝的好處
1.提高安全性
2.隔離復雜度
python 中屬性訪問權限
1.公開的(默認)在任何地方都能訪問到
2.私有的 僅在類內部可以使用
如何封裝:使用特殊語法:給要隱藏的變量名稱前面加上兩個下劃線__
外部無法訪問私有的內容
封裝方法
場景 一些方法的存在是為了 完成其他的功能 這些方法就不應該提供給外界 例如發動機中的打火這個功能
當一個方法中的代碼 太多時 我們需要將其拆分為不同的小函數 這個小函數不應該提供給外界
# class Person: # def __init__(self,name,sex,age,id_card):View Code# self.name=name # self.age=age # self.sex=sex # self.__id_card=id_card # # def say_hi(self): # print(‘name is%s age is%s id is%s‘%(self.name,self.age,self.__id_card)) # # # p1=Person(‘xxx‘,‘man‘,20,‘xxxxxxxxx‘) # p1.say_hi() # # print(p1.__id_card) 外部無法訪問
# class PC: # def boot(self): # self.__read_rom() # self.__boot_bios() # self.__read_opt() # self.__boot_gui() # print(‘電腦啟動成功!‘) # # # def __read_rom(self): # print(‘讀取rom中數據‘) # def __boot_bios(self): # print(‘啟動BIOS系統‘)View Code# def __read_opt(self): # print(‘讀取並執行操作系統命令‘) # def __boot_gui(self): # print(‘啟動用戶界面‘) # p1=PC() # p1.boot() # p1.__boot_gui()
訪問器與設置器
私有屬性 外界無法完全使用 那就沒有意義
我們可以定義訪問方法和設置方法
1.提供對私有屬性的訪問修改
2.增加額外的判斷邏輯
問題 :訪問和修改私有屬性的寫法與普通屬性的寫法不一致
對於使用而言更復雜了
使用property裝飾器 可以將一個方法偽裝成一個普通屬性 這樣對於使用者而言 使用方式就一致了
property 弊端是不能增加額外的參數 只能有一個參數self
訪問器
@property 用點來訪問你屬性時觸發
設置器
@屬性名稱.setter 用點來設置屬性時觸發 p1.id_card=‘123‘
限制刪除器
@屬性名稱.deleter 用del刪除屬性時觸發 del.p1.id_card
python是通過變形的方式 拉完成私有化操作
具體:把雙下劃線開頭的名字 在名字前添加一個_類名
發生變形操作是在定義階段就發生了 並且只發生了一次
默認情況下 子類無論是類的內部還是外部都是不能訪問父類的私有屬性的 但是可以強行訪問
# class Person: # def __init__(self,name,sex,age,id_card): # self.name=name # self.age=age # self.sex=sex # self.__id_card=id_card # # def say_hi(self): # print(‘name is%s age is%s id is%s‘%(self.name,self.age,self.__id_card)) # # #訪問器 # def get_id_card(self,pwd): # if pwd==‘123321‘: # return self.__id_card # else: # print(‘沒有訪問權限!‘) # # #設置器 # def set_id_card(self,new_id): # if len(new_id)==17or len(new_id)==18: # self.__id_card=new_id # else: # print(‘身份證格式錯誤!‘) # # p1=Person(‘xxx‘,‘man‘,29,‘11111112223546987‘) # # print(p1.get_id_card(‘123321‘)) # # p1.set_id_card(‘14785236996325874‘) # print(p1.get_id_card(‘123321‘))View Code
# class Person: # def __init__(self,name,id_card): # self.name=name # self.__id_card=id_card # # @property # def id_card(self): # return self.__id_card # # @id_card.setter # def id_card(self,new_id): # self.__id_card=new_id # # @id_card.deleter # def id_card(self): # print(‘你即將刪除身份證了‘) # self.__dict__.pop(‘_Person__id_card‘) # # p1 =Person(‘xxx‘,‘123123‘) # print(p1.__dict__) # p1.id_card=1111111 # # del p1.id_card # print(p1.__dict__)View Code
interface 接口
一組功能集合體
好處:用於提高程序的擴展性
接口用於定義一組功能,後續的程序只要按照接口來實現 就能被使用
可以將接口理解為一套規範
抽象類
使用class來模擬接口的問題是 不能強行限制子類必須實現接口的方法
抽象在這裏指的是 不具體 不清晰 看不懂
如果一個方法沒有實現體 那麽這個方法就可以稱之為抽象方法
如果一個類中存在抽象方法 那麽這個類也是抽象的
抽象類也是用於提高擴展性的 與接口相似的是也可以作為一套規範
比接口強大的地方在於 可以強行限制子類必須實現父類中聲明的方法
抽象類無法直接實例化 只能由子類繼承之後覆蓋所有的抽象方法 才能實例化
import abc # abstructclass class Computer(metaclass=abc.ABCMeta): @abc.abstractmethod def boot(self): pass @abc.abstractmethod def close(self): pass # @abc.abstractmethod def working(self): pass class NoteBook(Computer): def boot(self): print("筆記本開機啦") def close(self): print("筆記本關機啦") def working(self): print("筆記本正在計算") n1 = NoteBook() n1.boot() n1.working() n1.close()ABC
面向對象--封裝 多態