?
1.接口類,抽象類.
2.鴨子類型(Python多態)(Python三大特性之一)Python封裝
1.接口類和抽象類只是在工作中書寫的一種規范.
class QQ:
def? pay(self,money):
print("使用QQ支付%s"%money)
class Ali:
def pay(self,money):
print("使用支付寶支付%s"%money)
q = QQ()
q.pay(100)
a = Ali()
a.pay(200)
上面的例子,沒有統一化.不方便之后的開發
class QQ:
def pay(self,money):
print("使用QQ支付%s"%money)
class Ali:
def pay(self,money):
print("使用支付寶支付%s"%money)
def pay(self,money):
self.pay(money)
q = QQ()
a = Ali() #這樣就實現了統一化
pay(q,100)
pay(a,200)
以上這版實現了統一化,但是交接的時候,新來的看不懂就會按照自己的方法寫.看下面
class QQ:
def pay(self,money):
print("使用QQ支付%s"%money)
class Ali:
def pay(self,money):
print("使用支付寶支付%s"%money)
class Wechat:
def wepay(self,money):
print("使用微信支付%s"%money)
def pay(self,money):
self.pay(money)
q = QQ()
a = Ali()
pay(q,100)
pay(a,200)
w = Wechat() #新來的員工按照自己方法添加了一種,但是不規范.
w.wepay(500)
我們看一下下面的方法.
class Payment:
def pay(self):pass
class QQ(Payment):
def pay(self,money):
print("使用QQ支付%s"%money)
class Ali(Payment):
def pay(self,money):
print("使用支付寶支付%s"%money)
class Wechat(Payment):
def pay(self,money):
print("使用微信支付%s"%money)
def pay(self,money):
self.pay(money)
q = QQ()
a = Ali()
w = Wechat()
pay(q,100)
pay(a,200)
pay(w,500)
以上便是為了規避方法不統一的方法.下面的例子便是強制統一,不同一便報錯.
from abc import ABCMeta , abstractmethod
class Payment(metaclass = ABCMeta):
@abstractmethod
def pay(self):pass
class? QQ(Payment):
def pay(self,money):
print("使用QQ支付%s"%money)
class Ali(Payment):
def pay(self,money):
print("使用支付寶支付%s"%money)
class Wechat(Payment):
def pay(self,money):
print("使用微信支付%s"%money)
def pay(self,money):
self.pay(money)
q = QQ()
a = Ali()
w = Wechat()
pay(q,100)
pay(a,200) #強制統一化.沒有統一便會報錯
pay(w,500)
抽象類(接口類)用處:在工作中,如果要是規定幾個類必須有一樣的方法,要抽象類.制定一個規范,強制其有此方法.
Python沒有多態的概念,但是Python崇尚鴨子類型.
Python中好多不同類但同名的方法不是強制規定,而是約定俗成的,像str,list,tuple這三種類,都同樣具有index方法,而且功能相似,則他們三個互稱為鴨子.
封裝就是將一些屬性或者方法(有用的信息)放置在一個空間中.
1.封裝? ? 對象的封裝
class? A:
def __init__(self,name,age):
self.name? = name
self.age = age
p = A("alex",23)
print(p.name)
2.封裝(私有成員)
類的結構分析:
class Person:
mind = "有思想" #第一部分:所有的公有靜態變量,公有靜態字段
__level = "高等動物" #第一步分:私有靜態變量,私有靜態字段
def __init__(self,name,age,sex): #構造方法,第二部分:動態方法,方法(函數)
self.name = name
self.age = age #公有對象屬性
self.__sex = sex #私有對象屬性
def func(self): #第二部分:普通方法
print(666)
def __func1(self): #第二部分:私有方法
print(777)
@staticmethod #靜態方法
def f2():pass
@classmethod #類方法
def f2(self):pass
@property #屬性
def hex(self):pass
類的整體分類:
第一部分:公有靜態字段: mind = "有思想"
私有靜態字段: __level = "高等動物"
第二部分:特殊方法(__init__,__str__ ....)
普通方法:def func(self)
私有方法:def __func1(self)
類方法:@classmethod
靜態方法:@staticmethod
屬性:@property
私有成員:私有靜態字段,私有屬性,私有方法.在變量前加__雙下劃線.
class Animal:
__cloth = "有皮毛"
class Person(Animal):
mind = "有思想"
__level = "高等動物"
def __init__(self,name,age):
self.name = name
self.age = age
?? def func(self):
print(self.__level) #類自己在內部訪問自己的私有屬性
print(self._Animal__cloth) #知道這種方法可以,但是禁止使用.
print(self.__cloth) #派生類不可訪問父類的私有屬性
在類的外面訪問:私有靜態字段是訪問不到的.
p = Person("alex",100)
print(p.mind)
print(p.__level) #這樣訪問會報錯.
print(Person.__level) #這樣訪問也是會報錯的.
print(Person.__dict__)
print(Person._Person__level) #這個方法知道就可以了,但是禁止使用.
#可以通過? ?對象._類名__變量名? 類名._類名__變量名? 可以訪問到,但是絕對不要這樣做
在類的內部: 私有靜態字段是可以訪問的.
p.func()
父類的私有字段,派生類是否可以訪問? 答案是:不可以
print(p.__cloth)
p.func() #這兩種都會報錯.因為在外部是不可訪問父類的私有字段.
私有方法:
class Animal:
def f1(self):
print(111)
class Person(Animal):
def __init__(self,name,age,sex):
self.name = name
self.age = age?
self.__sex = sex
def __func(self):
print(6666)
def func1(self):
self.__func()
def func2(self):
self.__f1()
類外面訪問不到:
p = Person("oldboy",200)
p.__func()
類的內部可以訪問:
p.func1()
派生類也是訪問不到的
p.func2()
私有屬性也是類外部不能訪問,派生類不能訪問,只能類內部訪問.
總結:對于私有成員來說,加載到內存時,都會加上_類名__變量名,所以在類的外部或者派生類中都不可訪問.
為什么設置私有成員?
有些變量,方法,屬性只在類內部進行使用即可不便于(不允許)類外部或者派生類去調用.
class A:
def __init__(self):
self.__func()
def __func(self):
print("in? ?A")
class B(A):
def __func(self):
print("in? ?B")
b = B()
這是一道面試題, 打印的結果是什么,為什么結果是這樣的.
?