程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Python >> 面向對象(一)

面向對象(一)

編輯:Python

面向對象編程(Object Oriented Programming,OOP)
面向過程編程最易被初學者接受,其往往用一長段代碼來實現指定功能,開發過程中最常見的操作就是粘貼復制,即:將之前實現的代碼塊復制到現需功能處。
注:Java和C#來只支持面向對象編程,而python比較靈活即支持面向對象編程也支持函數式編程

面向對象三大特性:封裝繼承多態

一、封裝

封裝,顧名思義就是將內容封裝到某個地方,以後再去調用被封裝在某處的內容。
調用被封裝的內容時,有兩種情況:

  1. 通過對象直接調用
  2. 通過self間接調用
#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()

(1) 單繼承

優先級是,先子類後父類

(2) 多繼承

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

(3) 執行父類的構造方法

#方法一: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)

五、舊式類與新式類

  1. 在python2.x的版本才有新式類和舊式類之分。
  2. 舊式類定義class AA,新式類class AA(object)
  3. 在多重繼承的查找和調用方法上,舊式類是深度優先,新式類是廣度優先
  4. 所以對於python3的多層繼承來說,因為都是新式類,總是從左到右,廣度優先的方式進行。

(1) 定義形式

#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'>

(2) 多重繼承時的查找規則

#舊式類的深度優先查找
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()
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved