(繼承補充)組合
?obj=fun()#對象
?obj.attr=foo()#對象的屬性等于另一個對象
?什么是組合:?
?? A類的對象具備某一個屬性,該屬性的值是B類的對象
? ?基于這種方式就把A類與B類組合到一起
?? 對象既能使用A類中的數據與功能,也能使用B類中的數據與功能
?為什么要用組合:
?? 組合與繼承的作用一樣,都是用來減少類與類之間的重復代碼
?#組合不屬于繼承
?#類使用將變量及處理其的函數捆綁起來
?#繼承是強耦合,組合是解耦合
?如何用組合:
??class People:
??? def __init__(self,name,age):
???? self.name=name
???? self.age=age
???? self.eat=[]
??? def tell_eat(self):
??? ?for i in self.eat:
???? ?i.tell_info()
?????
??class Eat:
?? ?def __init__(self,e_name,e_price):
???? self.e_name=e_name
???? self.e_price=e_price
??? def tell_info(self):
???? print('食物%s 價格%s'%(self.e_name,self.e_price))
?obj=fun()#對象
?obj.attr=foo()#對象的屬性等于另一個對象
?什么是組合:?
?? A類的對象具備某一個屬性,該屬性的值是B類的對象
? ?基于這種方式就把A類與B類組合到一起
?? 對象既能使用A類中的數據與功能,也能使用B類中的數據與功能
?為什么要用組合:
?? 組合與繼承的作用一樣,都是用來減少類與類之間的重復代碼
?#組合不屬于繼承
?#類使用將變量及處理其的函數捆綁起來
?#繼承是強耦合,組合是解耦合
?如何用組合:
??class People:
??? def __init__(self,name,age):
???? self.name=name
???? self.age=age
???? self.eat=[]
??? def tell_eat(self):
??? ?for i in self.eat:
???? ?i.tell_info()
?????
??class Eat:
?? ?def __init__(self,e_name,e_price):
???? self.e_name=e_name
???? self.e_price=e_price
??? def tell_info(self):
???? print('食物%s 價格%s'%(self.e_name,self.e_price))
p=People('張三',18)
??eat1=Eat('肯德雞',38)
??eat2=Eat('烤乳豬',120)
??p.eat.append(eat)
??
?多態與多態性
??????? 什么是多態:
????? 同一種事物有多種形態在程序中用繼承可以表現出多態
??????? 多態性:
????? 在多態的背景下,可以在不用考慮對象具體類型的前提下而直接使用對象
????? 多態性的精髓:統一
??import abc
??class Animal(metaclass=abc.ABCMeta):#強制子類使用這套標準中加@..的名字,子類沒有報錯
?? ?@abc.abstractmethod?? #被強制的名字
?? ?def speak(self):
??? ?pass
????
??? def run(self):
??? ?pass
??# Animal() # 父類只是用來建立規范的,不能用來實例化的,更無需實現內部的方法
??eat1=Eat('肯德雞',38)
??eat2=Eat('烤乳豬',120)
??p.eat.append(eat)
??
?多態與多態性
??????? 什么是多態:
????? 同一種事物有多種形態在程序中用繼承可以表現出多態
??????? 多態性:
????? 在多態的背景下,可以在不用考慮對象具體類型的前提下而直接使用對象
????? 多態性的精髓:統一
??import abc
??class Animal(metaclass=abc.ABCMeta):#強制子類使用這套標準中加@..的名字,子類沒有報錯
?? ?@abc.abstractmethod?? #被強制的名字
?? ?def speak(self):
??? ?pass
????
??? def run(self):
??? ?pass
??# Animal() # 父類只是用來建立規范的,不能用來實例化的,更無需實現內部的方法
class People(Animal):
?? ?def speak(self):
???? print('say hello')
?? ?def speak(self):
???? print('say hello')
class Dog(Animal):
??? def speak(self):
???? print('汪汪汪')
??? def run(self):
??? ?pass
???????????
??????? python推崇鴨子類型:(像什么,就有什么的特征)
??????????? class Txt:
??????????????? def read(self):
??????????????????? pass
??????????? class Disk:
??????????????? def read(self):
??????????????????? pass
?????
#BMI=體重(kg)÷身高^2(m)
#首先需要明確。bmi是算出來的,不是一個固定死的值,很明顯人的bmi值聽起來更像一個名詞而非動詞,于是我們需要為bmi這個函數添加裝飾器將其偽裝成一個數據屬性
# @property裝飾器是用來將類內的函數屬性偽裝成數據屬性
#@property裝飾的函數可以調setter及deleter
# class People:
#???? def __init__(self,name):
#???????? self.__name=name
#
#???? @property
#???? def name(self):
#???????? return '<名字:%s>' %self.__name
#
#???? @name.setter
#???? def name(self,obj):
#???????? if type(obj) is not str:
#???????????? print('name必須為str類型')
#???????????? return
#???????? self.__name=obj
#
#???? @name.deleter
#???? def name(self):
#???????? # print('不讓刪')
#???????? del self.__name
#
# obj=People('egon')
#
# # print(obj.name)
# # obj.name='EGON'
# # obj.name=123
# # print(obj.name)
#
# del obj.name
# print(obj.__dict__)
??? def speak(self):
???? print('汪汪汪')
??? def run(self):
??? ?pass
???????????
??????? python推崇鴨子類型:(像什么,就有什么的特征)
??????????? class Txt:
??????????????? def read(self):
??????????????????? pass
??????????? class Disk:
??????????????? def read(self):
??????????????????? pass
?????
#BMI=體重(kg)÷身高^2(m)
#首先需要明確。bmi是算出來的,不是一個固定死的值,很明顯人的bmi值聽起來更像一個名詞而非動詞,于是我們需要為bmi這個函數添加裝飾器將其偽裝成一個數據屬性
# @property裝飾器是用來將類內的函數屬性偽裝成數據屬性
#@property裝飾的函數可以調setter及deleter
# class People:
#???? def __init__(self,name):
#???????? self.__name=name
#
#???? @property
#???? def name(self):
#???????? return '<名字:%s>' %self.__name
#
#???? @name.setter
#???? def name(self,obj):
#???????? if type(obj) is not str:
#???????????? print('name必須為str類型')
#???????????? return
#???????? self.__name=obj
#
#???? @name.deleter
#???? def name(self):
#???????? # print('不讓刪')
#???????? del self.__name
#
# obj=People('egon')
#
# # print(obj.name)
# # obj.name='EGON'
# # obj.name=123
# # print(obj.name)
#
# del obj.name
# print(obj.__dict__)
封裝
?self.__name=name #_類名__name 定義階段轉形
?什么是封裝?
?? 裝:往容器/名稱空間里存入名字
?? 封:代表將存放于名稱空間中的名字給藏起來,這種隱藏對外不對內
補充說明:封裝絕對不是單純意義的隱藏
?? 需知定義屬性的目的就是為了讓使用者去用,使用者要想使用類內部隱藏的屬性
?? 需要類的設計者在類內部開一個接口(定義一個方法),在該方法內訪問隱藏的屬性
? ?,使用者以后就通過該方法來“間接地”訪問內部隱藏的屬性
?? 作為類的設計者可以在接口之上附加任意邏輯從而嚴格控制類的使用者對屬性的操作
?如何封裝?
??????? 1. __開頭的屬性實現的隱藏僅僅只是一種語法意義上的變形,并不會真的限制類外部的訪問
??????? 2. 該變形操作只在類定義階段檢測語法時發生一次,類定義階段之后新增的__開頭的屬性并不會變形
??????? 3. 如果父類不想讓子類覆蓋自己的屬性,可以在屬性前加__開頭
?封裝形式?
??封裝數據屬性:把數據屬性封裝起來,然后需要開辟接口給類外部的使用者使用,好處是我們可以在接口之上添加控制邏輯,從而嚴格空間訪問者對屬性的操作
??class People:
??????????????? def __init__(self,name):
??????????????????? self.__name=name
?? 需知定義屬性的目的就是為了讓使用者去用,使用者要想使用類內部隱藏的屬性
?? 需要類的設計者在類內部開一個接口(定義一個方法),在該方法內訪問隱藏的屬性
? ?,使用者以后就通過該方法來“間接地”訪問內部隱藏的屬性
?? 作為類的設計者可以在接口之上附加任意邏輯從而嚴格控制類的使用者對屬性的操作
?如何封裝?
??????? 1. __開頭的屬性實現的隱藏僅僅只是一種語法意義上的變形,并不會真的限制類外部的訪問
??????? 2. 該變形操作只在類定義階段檢測語法時發生一次,類定義階段之后新增的__開頭的屬性并不會變形
??????? 3. 如果父類不想讓子類覆蓋自己的屬性,可以在屬性前加__開頭
?封裝形式?
??封裝數據屬性:把數據屬性封裝起來,然后需要開辟接口給類外部的使用者使用,好處是我們可以在接口之上添加控制邏輯,從而嚴格空間訪問者對屬性的操作
??class People:
??????????????? def __init__(self,name):
??????????????????? self.__name=name
def tell_name(self):
??????????????????? # 添加邏輯
??????????????????? return self.__name
?????
??封裝函數屬性:隔離復雜度
??????????? class ATM:
??????????????? def __card(self):
??????????????????? print('插卡')
??????????????? def __auth(self):
??????????????????? print('用戶認證')
??????????????? def __input(self):
??????????????????? print('輸入取款金額')
??????????????? def __print_bill(self):
??????????????????? print('打印賬單')
??????????????? def __take_money(self):
??????????????????? print('取款')
??????????????????? # 添加邏輯
??????????????????? return self.__name
?????
??封裝函數屬性:隔離復雜度
??????????? class ATM:
??????????????? def __card(self):
??????????????????? print('插卡')
??????????????? def __auth(self):
??????????????????? print('用戶認證')
??????????????? def __input(self):
??????????????????? print('輸入取款金額')
??????????????? def __print_bill(self):
??????????????????? print('打印賬單')
??????????????? def __take_money(self):
??????????????????? print('取款')
def withdraw(self):
??????????????????? self.__card()
??????????????????? self.__auth()
??????????????????? self.__input()
??????????????????? self.__print_bill()
??????????????????? self.__take_money()
??封裝的終極奧義:明確地區分內外,對外是隱藏的,對內是開放的
??????????????????? self.__card()
??????????????????? self.__auth()
??????????????????? self.__input()
??????????????????? self.__print_bill()
??????????????????? self.__take_money()
??封裝的終極奧義:明確地區分內外,對外是隱藏的,對內是開放的