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
類的成員、成員修飾符、類的特殊成員

class Province:
country = '中國' # 靜態(tài)字段
def __init__(self, name):
self.name = name # 普通字段
obj = Province('河北省') # 直接訪問普通字段
print obj.name
Province.country # 直接訪問靜態(tài)字段

由上圖可是:
靜態(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)建)

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

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)先方式查找

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í)
