python全棧開發-面向對象-進階2

python_day_19python

今日主要內容:程序員

  • 1.抽象類,接口類
  • 2.多態
  • 3.封裝

1.抽象類,接口類面試

python 沒有接口這個概念
接口類,抽象類: 制定一個規範.

舉個栗子:
你的項目經理提一個需求,讓你作一個支付功能.
初版:
class Alipay:
    def __init__(self,money):
        self.money = money

    def pay(self):
        print('使用支付寶支付了%s' %self.money)


class Jdpay:
    def __init__(self, money):
        self.money = money

    def pay(self):
        print('使用京東支付了%s' % self.money)

a1 = Alipay(200)
a1.pay()

j1 = Jdpay(100)
j1.pay()

 

經理看了,而後讓你改進,讓你支付的方式同樣算法

第二版:微信

class Alipay:
    def __init__(self,money):
        self.money = money

    def pay(self):
        print('使用支付寶支付了%s' %self.money)


class Jdpay:
    def __init__(self, money):
        self.money = money

    def pay(self):
        print('使用京東支付了%s' % self.money)

def pay(obj):
    obj.pay()

a1 = Alipay(200)
j1 = Jdpay(100)
pay(a1)  # 歸一化設計
pay(j1)

第三版,野生程序員來了.......要增長一個微信支付的功能.
class Alipay:
    def __init__(self,money):
        self.money = money

    def pay(self):
        print('使用支付寶支付了%s' %self.money)

class Jdpay:
    def __init__(self, money):
        self.money = money

    def pay(self):
        print('使用京東支付了%s' % self.money)

class Wechatpay:

    def __init__(self,money):
        self.money = money

    def weixinpay(self):
        print('使用微信支付了%s' % self.money)


def pay(obj):
    obj.pay()

a1 = Alipay(200)
j1 = Jdpay(100)
pay(a1)  # 歸一化設計
pay(j1)

w1 = Wechatpay(300)
w1.weixinpay()

 

經理看了以爲很亂,打回去從新修改,制定規則,抽象類,接口類
第四版:
from abc import ABCMeta,abstractmethod

class Payment(metaclass=ABCMeta):  # 抽象類(接口類):
    @abstractmethod
    def pay(self): pass  # 制定了一個規範


class Alipay(Payment):
    def __init__(self,money):
        self.money = money

    def pay(self):
        print('使用支付寶支付了%s' %self.money)


class Jdpay(Payment):
    def __init__(self, money):
        self.money = money

    def pay(self):
        print('使用京東支付了%s' % self.money)

class Wechatpay(Payment):

    def __init__(self,money):
        self.money = money

    def pay(self):
        print('使用微信支付了%s' % self.money)


def pay(obj):
    obj.pay()
w1 = Wechatpay(200)
a1 = Alipay(200)
j1 = Jdpay(100)
pay(a1)  # 歸一化設計
pay(j1)
pay(w1)

 

 

2.多態.函數

python面向對象的三大特徵之一:
多態: python到處是多態.微信支付

python:弱類型語言
python 無論什麼類型,傳入函數,封裝到對象中均可以.
python的鴨子類型.
鴨子類型 : 看着像鴨子,他就是鴨子.
如下這些類 都互稱爲鴨子.
class Str:
    def index(self):
        pass

class List:
    def abc(self):
        pass

class Tuple:
    def rrr(self):
        pass

3.封裝
廣義的封裝: 實例化一個對象,給對象空間封裝一些屬性.
狹義的封裝: 私有制.
私有成員:私有靜態字段,私有方法,私有對象屬性
私有靜態字段
class B:
    __money = 100000

class A(B):
    name = 'alex'
    __age = 1000

    def func(self):
        print(self.__age)
        print(A.__age)    # 對於私有靜態字段,類的內部能夠訪問.
        print('func....')
    def func1(self):
        print(self.__money)
        print(A.__money)
a1 = A()
print(a1.name)
print(A.name)

print(a1.__age)  # 實例化對象不能訪問私有靜態字段
print(A.__age)  # 類名不能訪問私有靜態字段
對於私有靜態字段,類的外部不能訪問.

a1.func()

#對於私有靜態字段,類的內部能夠訪問.

a1.func1()

#對於私有靜態字段來講,只能在本類中內部訪問,類的外部,派生類均不可訪問.

#能夠訪問,可是工做中千萬不要用.
print(A._A__age)
print(A.__dict__)

#私有方法

class B:
    __money = 100000
    def __f1(self):
        print('B')

class A(B):
    name = 'alex'

    def __func(self):
        print('func....')

    def func1(self):
        # self.__func()   # 類的內部能夠訪問
        self.__f1()
a1 = A()
a1.__func()  # 類外部不能訪問
a1.func1()  # 類的內部能夠訪問
a1.func1()  # 類的派生類也不能訪問.

 


私有對象屬性同私有方法和私有靜態字段,類外部不能訪問,類的內部能夠訪問,類的派生類也不能訪問.

補充一個面試題:
3,下面代碼執行結果是什麼?爲何?
class Parent:
    def func(self):
        print('in Parent func')

    def __init__(self):
        self.func()

class Son(Parent):
    def func(self):
        print('in Son func')

son1 = Son()

流程圖;spa

結果圖;設計

 

緣由:

由於Son(),是實例化過程,而後自動執行__init__函數,Son類裏沒有,去父類裏找,而後執行父類的__init__方法,執行func方法,先從本身的類中找,有func,執行func,
打印in Son func

補充知識點:
MRO-C算法-python多繼承原理
class H:

    def bar(self):
        print('F.bar')
class G(H):

    def bar(self):
        print('F.bar')
class F(H):

    def bar(self):
        print('F.bar')
class E(G):

    def bar(self):
        print('E.bar')

class D(F):

    def bar(self):
        print('D.bar')


class C(E):
    def bar(self):
        print('C.bar')


class B(D):

    def bar(self):
        print('B.bar')


class A(B, C, D):

    def bar(self):
        print('A.bar')

a = A()
print(A.mro())

流程圖;3d

執行過程:

A(B,C,D)

首先找到A繼承的三個類的深度繼承順序,放到一個列表中
L[B] = [B,D,F,H] #B往上面的繼承順序
L[C] = [C,E,G,H] #C往上面的繼承順序
L[D] = [D,F,H] #D往上面的繼承順序

第二步:A本身的廣度,第一層
L[A] = [B,C,D]

每一個列表的第一個元素爲頭部,從第一個列表的頭部開始找,找其餘列表中尾部是否含有
這個類名,若是沒有,提取出來放到一個列表中,若是有,找下一個列表的頭部,循環下去
只要提取來一個,咱們就從第一個列表的頭部接着重複上面的操做.
1 [B,D,F,H] [C,E,G,H] [D,F,H] [B,C,D]
2 [D,F,H] [C,E,G,H] [D,F,H] [C,D] #提取了頭部的B,而後將其餘列表頭部的B刪除,並將B放到list中
3 [D,F,H] [E,G,H] [D,F,H] [D] #由於第一個列表的D在其餘列表的尾部存在,因此跳過D,而後找第二個列表的頭部C,提取了頭部的C,而後將其餘列表頭部的B刪除,並將B放到list中

.......

4 [H] [H] [H] []

list = [A,B,C,D,F,E,G,H,O]


2018-07-26  17:41:25

相關文章
相關標籤/搜索