python 面向?qū)ο蟮木幊?一)

python 同時支持面向?qū)ο缶幊毯秃瘮?shù)式編程的語言
python面向?qū)ο蟮闹黝}圍繞 類實例 兩個主題。
面向?qū)ο笕筇匦裕?strong>封裝、繼承多態(tài)

概念

1.對象:類的實例。對象具有兩個特征:狀態(tài)與行為。
2.類:用來描述具有相同的屬性和方法的對象的集合,類的組成=方法+行為
3.抽象:對現(xiàn)實世界問題和實體的本質(zhì)表現(xiàn),行為和特征建模,建立一個相關(guān)的子集,可以用于描述程序結(jié)構(gòu),從而實現(xiàn)這種模型。
4.封裝:對屬性和方法的載體類,只能通過其提供的接口(方法)來訪問,而把實現(xiàn)細(xì)節(jié)隱藏起來.python的類屬性都是公開的。
5.繼承:描述了子類屬性從祖先類繼承這樣一種方式。
6.多態(tài):同一消息可以根據(jù)發(fā)送對象的不同而采用多種不同的行為方式。

創(chuàng)建類

python 類是使用class關(guān)鍵詞來創(chuàng)建,即關(guān)鍵詞+類名

class ClassName():
    class_suit 
  • class_suit(類實體由類成員、方法、數(shù)據(jù)屬性組成)
  • 類中的函數(shù)第一個參數(shù)必須是self,
  • 類分為經(jīng)典類和新式類(如果 當(dāng)前類或者父類繼承了object類,那么該類便是新式類,否則便是經(jīng)典類。以后慢慢推薦用新式類寫)


    QQ20170709-223954@2x.png

類的成員、成員修飾符、類的特殊成員

Paste_Image.png
class Province:
    country = '中國'                     # 靜態(tài)字段
    def __init__(self, name):
        self.name = name                 # 普通字段

obj = Province('河北省')                 # 直接訪問普通字段
print obj.name
Province.country                        # 直接訪問靜態(tài)字段
Paste_Image.png

由上圖可是:
靜態(tài)字段在內(nèi)存中只保存一份
普通字段在每個對象中都要保存一份
應(yīng)用場景: 通過類創(chuàng)建對象時,如果每個對象都具有相同的字段,那么就使用靜態(tài)字段

方法:普通方法、靜態(tài)方法和類方法,三種方法在內(nèi)存中都?xì)w屬于類,區(qū)別在于調(diào)用方式不同。

class E():
    i=1
    def run(self):
         E.i +=1
         print('{0} is run ordinary method'.format(E.i))
    @staticmethod
    def eat():
        E.i +=1
        print('{0} is eat static method'.format(E.i))
    @classmethod
    def fool(cls):
        E.i +=1
        print('{0} is fool class method '.format(E.i))

e = E()
e.run()
E.eat()
E.fool()

輸出

2 is run ordinary method
3 is eat static method
4 is fool class method 

屬性:相當(dāng)一個bean里面的方法,做比較好的封裝一層,創(chuàng)建屬性有2中方式,一種是修飾器,一種是靜態(tài)字段,裝飾器方式針對經(jīng)典類和新式類又有所不同,下面例子針對新式類(圖中-今天方式創(chuàng)建 改為 靜態(tài)方式創(chuàng)建)


Paste_Image.png
self

引用地址:http://m.blog.csdn.net/happyjxt/article/details/50760467

QQ20170709-223954@2x.png

class Foo:
    def __init__(self, name, age):
        self.name = name
        self.age = age  
    def detail(self):
        print self.name
        print self.age  
obj1 = Foo('wupeiqi', 18)
obj1.detail()  # Python默認(rèn)會將obj1傳給self參數(shù),即:obj1.detail(obj1),所以,此時方法內(nèi)部的 self = obj1,即:self.name 是 wupeiqi ;self.age 是 18
obj2 = Foo('alex', 73)
obj2.detail()  # Python默認(rèn)會將obj2傳給self參數(shù),即:obj1.detail(obj2),所以,此時方法內(nèi)部的 self = obj2,即:self.name 是 alex ; self.age 是 78
繼承

· python是支持多繼承的語言
· python主要繼承的多個類時,尋找的繼承的方法主要2種,分別是:深度優(yōu)先廣度優(yōu)先
1、當(dāng)類是經(jīng)典類時,多繼承情況下,會按照深度優(yōu)先方式查找
2、當(dāng)類是新式類時,多繼承情況下,會按照廣度優(yōu)先方式查找

QQ20170709-223954@2x.png

eg1、

class A():
    def __init__(self):
        print('A start')
        print('A level')
class B(A):
    def __init__(self):
        print('B start')
        print('B level')
class C(A):
    def __init__(self):
        print('C start')
        print('C level')
class D(B,C):
    def __init__(self):
        print('D start')
        print('D level')
d=D();

以上程序輸入

D start
D level

假設(shè)把D類改造如下,其他沒有變化:

class D(B,C):
    pass

程序輸入

B start
B level

原因:程序首先在D類尋找init方法,程序發(fā)現(xiàn)沒有該方法后則尋找第一個父類的init的方法。

經(jīng)典類尋找

再次把B類改造如下,其他的沒有變化

class B(A):
   pass

程序輸入

A start
A  level

原因:查找順序:D --> B --> A --> C

新式類尋找

再次把A類改造成新式類,其他沒有變化

class A(object):
    def __init__(self):
        print('A start')
        print('A level')

程序輸入

C start
C  level

原因:查找順序:D --> B --> C --> A
備注:python3.0后多繼承來講,類都是新式類,所以繼承順序統(tǒng)一是廣式優(yōu)先進(jìn)行 

對于父類和子類重名時,又想使用父類的名字,這時可以使用關(guān)鍵詞super-只適合用于新式類
'''
class C(B):
def meth(self, arg):
super(C, self).meth(arg)
'''
1、super只能用于新式類
2、super不是父類,而是繼承順序的下一個類
3、 Python的多繼承類是通過mro的方式來保證各個父類的函數(shù)被逐一調(diào)用,而且保證每個父類函數(shù)
只調(diào)用一次(如果每個類都使用super)

class A(object):
    def __init__(self):
        print('A start')
        print('A level')
class B(A):
    def __init__(self):
        print('B start')
        print('B level')
        super(B, self).__init__()
class C(A):
    def __init__(self):
        print('C start')
        print('C level')
        super(C, self).__init__()
class D(C,B):
    def __init__(self):
        print('D start')
        print('D level')
        super(D, self).__init__()
d=D();

輸出結(jié)果

D start
D level
C start
C level
B start
B level
A start
A level

原因:新式類的尋找順序是D --> B --> C --> A,那么程序執(zhí)行D類的init方法中觸發(fā)super關(guān)鍵詞,D的繼承關(guān)系中的下一個類是B,那么把super.init轉(zhuǎn)化為B.init執(zhí)行。在執(zhí)行過程中觸發(fā)了super關(guān)鍵詞,D的繼承關(guān)系中B的下一個類是C,那么super.init轉(zhuǎn)化為C.init執(zhí)行

封裝

封裝:你錢包的有多少錢
封裝主要的原因:保護隱私隔離復(fù)雜度
在python中用雙下劃線的方式實現(xiàn)隱藏屬性,還有用property方式

每一個類的成員而言都有兩種形式,
1、公有成員,在任何地方都能訪問,類內(nèi)部可以訪問;派生類中可以訪問
2、私有成員,只有在類的內(nèi)部才能方法
私有成員命名時,前兩個字符是下劃線。(特殊成員除外,例如:init、call、dict等)

class C:
    def __init__(self):
        self.name = '公有字段'
        self.__foo = "私有字段"

備注:本文由部分引用。此文章只是用來學(xué)習(xí)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容