面向對象編程(Object Oriented Programming,OOP)
面向過程編程最易被初學者接受,其往往用一長段代碼來實現指定功能,開發過程中最常見的操作就是粘貼復制,即:將之前實現的代碼塊復制到現需功能處。
注:Java和C#來只支持面向對象編程,而python比較靈活即支持面向對象編程也支持函數式編程
面向對象三大特性:封裝、繼承、多態
封裝,顧名思義就是將內容封裝到某個地方,以後再去調用被封裝在某處的內容。
調用被封裝的內容時,有兩種情況:
#1. 通過對象直接調用
class Foo:
def __init__(self, name, age):
self.name = name
self.age = age
obj1 = Foo('morra', 18)
print obj1.name # 直接調用obj1對象的name屬性
print obj1.age # 直接調用obj1對象的age屬性
#2. 通過self間接調用
class Foo:
def __init__(self, name, age):
self.name = name
self.age = age
def detail(self):
print self.name
print self.age
obj1 = Foo('morra', 18)
obj1.detail() # Python默認會將obj1傳給self參數,所以,此時方法內部的 self = obj1
綜上所述,對於面向對象的封裝來說,其實就是使用__init__方法將內容封裝到對象中,然後通過對象直接或者self間接獲取被封裝的內容。
繼承,就是將多個類共有的方法提取到父類中,子類僅需繼承父類而不必一一實現每個方法。父類也叫基類,子類也叫派生類。
class Animals: #基類
def __init__(self, name):
self.name = name
def eat(self):
pass
def drink(self):
pass
class Dog(Animals): #派生類
def __init__(self, name):
self.name = name
def bark(self):
print('汪')
obj_dog = Dog('morra')
obj_dog.eat()
obj_dog.bark()
優先級是,先子類後父類
python可以同時繼承多個類(C# java是不可以的)。
優先級是,先子類後父類,父類裡面先左再右,廣度優先。
#新式類的廣度優先查找
class D(object):
def bar1(self):
print 'D.bar'
class C(D):
def bar(self):
print 'C.bar'
class B(D):
def bar(self):
print 'B.bar'
class A(B, C):
def bar(self):
print 'A.bar'
a = A()
# 執行bar方法時
# 查找順序:A --> B --> C --> D
# 在上述查找bar方法的過程中,一旦找到,則尋找過程立即中斷,便不會再繼續找了
a.bar()
#方法一:super,通過python多繼承的原則查找
class Animal:
def __init__(self):
print('A構造方法')
self.ty = "動物"
class Cat(Animal):
def __init__(self):
print('B構造方法')
self.n = "貓"
super(Cat,self).__init__() #執行父類的構造方法,推薦用super()
c = Cat()
print(c.__dict__)
# ---------
# B構造方法
# A構造方法
# {'n': '貓', 'ty': '動物'}
#方法二:Animal,直接指定基類(不建議使用)
class Animal:
def __init__(self):
print('A構造方法')
self.ty = "動物"
class Cat(Animal):
def __init__(self):
print('B構造方法')
self.n = "貓"
Animal.__init__(self) #不推薦
c = Cat()
print(c.__dict__)
# ---------
# B構造方法
# A構造方法
# {'n': '貓', 'ty': '動物'}
Pyhon不支持Java和C#這一類強類型語言中多態的寫法,但是原生多態,其Python崇尚“鴨子類型”。
python的“鴨子類型”:
class F1:
pass
class S1(F1):
def show(self):
print 'S1.show'
class S2(F1):
def show(self):
print 'S2.show'
def Func(obj):
print obj.show()
s1_obj = S1()
Func(s1_obj)
s2_obj = S2()
Func(s2_obj)
class Foo:
def __init__(self,name):
self.name = name 對象.屬性=變量
pass
def show(self):
pass
obj = Foo('morra')
r = hasattr(Foo, 'show') #只能找類裡的成員
print(r) # True
r = hasattr(obj, 'name') #在對象中可以找自己的屬性,就是self.name中的name屬性
print(r) # True
r = hasattr(obj, 'show') #對象中也可以找類的成員,是通過python裡的類對象指針來實現的
print(r) # True
m = __import__('s1',fromlist=True) #通過反射獲取模塊
class_name = getattr(m,"Foo") #在模塊中獲取Foo類
obj = class_name('morra') #實例化
val = getattr(obj,'name') #獲取類中的name屬性
print(val)
#python2.7中的舊式類
class AA():
pass
a = AA()
print(type(a)) #<type 'instance'>
print(type(AA)) #<type 'classobj'>
#python2.7中的新式類
class AA(object):
pass
a = AA()
print(type(a)) #<class '__main__.AA'>
print(type(AA)) #<type 'type'>
#python3中的新式類
class AA(object):
pass
a = AA()
print(type(a)) ## <class '__main__.AA'>
print(type(AA)) # <class 'type'>
#舊式類的深度優先查找
class D:
def bar1(self):
print 'D.bar'
class C(D):
def bar(self):
print 'C.bar'
class B(D):
def bar(self):
print 'B.bar'
class A(B, C):
def bar(self):
print 'A.bar'
a = A()
# 執行bar方法時
# 查找順序:A --> B --> D --> C
# 在上述查找bar方法的過程中,一旦找到,則尋找過程立即中斷,便不會再繼續找了
a.bar()
#新式類的廣度優先查找
class D(object):
def bar1(self):
print 'D.bar'
class C(D):
def bar(self):
print 'C.bar'
class B(D):
def bar(self):
print 'B.bar'
class A(B, C):
def bar(self):
print 'A.bar'
a = A()
# 執行bar方法時
# 查找順序:A --> B --> C --> D
# 在上述查找bar方法的過程中,一旦找到,則尋找過程立即中斷,便不會再繼續找了
a.bar()