Python——面向對象、綁定對象、組合

1. 面向過程VS面向對象

(1)面向過程

  核心是過程(流水線式思惟),過程即解決問題的步驟,面向過程的設計就比如精心設計好一條流水線,考慮周全何時處理什麼東西。html

  優勢是:極大的下降了寫程序的複雜度,只須要順着要執行的步驟,堆疊代碼便可。python

  缺點是:一套流水線或者流程就是用來解決一個問題,代碼牽一髮而動全身。linux

  應用場景:一旦完成基本不多改變的場景,著名的例子有Linux內核,git,以及Apache HTTP Server等。git

 (2)面向對象

  核心是對象(上帝式思惟),要理解對象爲什麼物,必須把本身當成上帝,上帝眼裏世間存在的萬物皆爲對象,不存在的也能夠創造出來。面向對象的程序設計比如如來設計西遊記,如來要解決的問題是把經書傳給東土大唐,如來想了想解決這個問題須要四我的:唐僧,沙和尚,豬八戒,孫悟空,每一個人都有各自的特徵和技能(這就是對象的概念,特徵和技能分別對應對象的屬性和方法),然而這並很差玩,因而如來又安排了一羣妖魔鬼怪,爲了防止師徒四人在取經路上被搞死,又安排了一羣神仙保駕護航,這些都是對象。而後取經開始,師徒四人與妖魔鬼怪神仙互相纏鬥着直到最後取得真經。如來根本不會管師徒四人按照什麼流程去取。ide

  優勢是:解決了程序的擴展性。對某一個對象單獨修改,會馬上反映到整個體系中,如對遊戲中一我的物參數的特徵和技能修改都很容易。函數

  缺點:可控性差,沒法向面向過程的程序設計流水線式的能夠很精準的預測問題的處理流程與結果,面向對象的程序一旦開始就由對象之間的交互解決問題即使是上帝也沒法預測最終結果。因而咱們常常看到一個遊戲人某一參數的修改極有可能致使陰霸的技能出現,一刀砍死3我的,這個遊戲就失去平衡。spa

  應用場景:需求常常變化的軟件,通常需求的變化都集中在用戶層,互聯網應用,企業內部軟件,遊戲等都是面向對象的程序設計大顯身手的好地方。設計

2. 相關名詞概念

(1)類

  類:具備相同特徵的一類事物(人、狗、老虎)3d

(2)對象(實例)

  對象/實例:具體的某一個事物(隔壁阿花、樓下旺財)code

(3)實例化

  實例化:類——>對象的過程(這在生活中表現的不明顯,咱們在後面再慢慢解釋)

3. 類的相關知識

(1)類的定義

class Person:   #定義一個類:Person
    role = 'person'  #人的角色屬性都是人
    def walk(self):  #人均可以走路,也就是有一個走路方法,也叫動態屬性
        print("person is walking...")
類的定義

(2)類的做用

  <1>屬性引用

    屬性引用(類名.屬性)

class Person:   #定義一我的類
    role = 'person'  #人的角色屬性都是人
    def walk(self):  #人均可以走路,也就是有一個走路方法
        print("person is walking...")


print(Person.role)  #查看人的role屬性
print(Person.walk)  #引用人的走路方法,注意,這裏不是在調用
屬性引用

  <2>實例化

    語法:對象名 = 類名(參數)

    類名加括號就是實例化,會自動觸發__init__函數的運行,能夠用它來爲每一個實例定製本身的特徵

    實例化的過程就是類——>對象的過程

  本來咱們只有一個Person類,在這個過程當中,產生了一個egg對象,有本身具體的名字、攻擊力和生命值。

egg = Person('egon')  #類名()就等於在執行Person.__init__()
#執行完__init__()就會返回一個對象。這個對象相似一個字典,存着屬於這我的自己的一些屬性和方法。

  <3> 查看屬性&調用方法

print(egg.name)     #查看屬性直接 對象名.屬性名
print(egg.walk())   #調用方法,對象名.方法名()

  <4> 關於self

    self:在實例化時自動將對象/實例自己傳給__init__的第一個參數,通常不作修改。

(3)類屬性的補充

  <1> 咱們定義的類的屬性到底存到哪裏了?

    有兩種方式查看
      dir(類名):查出的是一個名字列表
      類名.__dict__:查出的是一個字典,key爲屬性名,value爲屬性值

  <2> 特殊的類屬性    

    類名.__name__# 類的名字(字符串)
    類名.__doc__# 類的文檔字符串
    類名.__base__# 類的第一個父類(在講繼承時會講)
    類名.__bases__# 類全部父類構成的元組(在講繼承時會講)
    類名.__dict__# 類的字典屬性
    類名.__module__# 類定義所在的模塊
    類名.__class__# 實例對應的類(僅新式類中)

4. 對象的相關知識

  對象是關於類而實際存在的一個例子,即實例

  對象/實例只有一種做用:屬性引用

  動態屬性:方法調用

print(egg.attack)

  定義及調用的固定模式

class 類名:
    def __init__(self,參數1,參數2):
        self.對象的屬性1 = 參數1
        self.對象的屬性2 = 參數2

    def 方法名(self):pass

    def 方法名2(self):pass

對象名 = 類名(1,2)  #對象就是實例,表明一個具體的東西
                  #類名() : 類名+括號就是實例化一個類,至關於調用了__init__方法
                  #括號裏傳參數,參數不須要傳self,其餘與init中的形參一一對應
                  #結果返回一個對象
對象名.對象的屬性1   #查看對象的屬性,直接用 對象名.屬性名 便可
對象名.方法名()     #調用類中的方法,直接用 對象名.方法名() 便可

小結
View Code

 5. 對象之間的交互

  實例化一隻實實在在的二哈

ha2 = Dog('二愣子','哈士奇',10,1000)  #創造了一隻實實在在的狗ha2

  交互 egon打ha2一下

print(ha2.life_value)         #看看ha2的生命值
egg.attack(ha2)               #egg打了ha2一下
print(ha2.life_value)         #ha2掉了10點血

 6. 類命名空間與對象、實例的命名空間

建立一個類就會建立一個類的名稱空間,用來存儲類中定義的全部名字,這些名字稱爲類的屬性

建立一個對象/實例就會建立一個對象/實例的名稱空間,存放對象/實例的名字,稱爲對象/實例的屬性

(1)類的兩種屬性

  靜態屬性和動態屬性

  <1> 靜態屬性

    直接在類中定義的變量——共享給全部對象的

  <2> 動態屬性

    定義在類中的方法——綁定到全部對象的

class Course:
    language = 'Chinese'    # 靜態屬性
    def __init__(self,teacher,name,period,price):
        self.teacher = teacher,
        self.name = name,
        self.period = period,
        self.price = price

    def func(self):
        print('pass')

python = Course('egon','python','6 months',20000)
linux = Course('eva','linux','6 months',20000)
示例代碼
print(python.language)  # English   類中的靜態變量能夠被對象調用
print(Course.language)  # English   類中的靜態變量能夠被類調用
linux.func()            # pass      類中的動態變量能夠被對象調用
Course.func(linux)      # pass      類中的動態變量能夠被類調用(須要傳參)
類中靜/動態對象的調用
Course.language = 'English' # 靜態屬性修改
print(Course.language)  # English  修改爲功
# Course.__dict__['language'] = 'Chinese' # 不能夠這麼修改
# print(Course.language)  # 報錯
靜態屬性的修改:不能用dict修改

(2)靜態變量的修改

  <1> 類修改靜態變量:

    language = 'Chinese' 字符串【不可變數據類型】

  <2> 對象修改靜態屬性

    對於【不可變數據類型】來講
      類變量最好用類名操做(如上例子)
      由於用對象修改不是真正的修改,而是在對象本身的空間中建立新的同名屬性
      只有建立的同名屬性刪除後,才能夠調用類中的靜態屬性

print(python.language)  # English
print(linux.language)   # English
python.language = 'Chinese'     # 不能修改靜態變量language,而是在本身的空間中建立了language的
print(python.language)  # Chinese
print(python.__dict__)  # {'teacher': ('egon',), ... , 'price': 20000, 'language': 'Chinese'}
print(linux.language)   # English
print(linux.__dict__)   # {'teacher': ('eva',), ... , 'price': 20000}

del python.language # 本身建立的language刪除以後,才能使用類中的靜態變量
print(python.language)  # English

    對於【可變數據類型】來講
      類中的靜態變量:language = ['Chinese'] 列表【可變數據類型】
       <1> 對象名的修改是共享的

python.language[0] = 'English'
print(python.language)  # ['English']
print(python.__dict__)  # {'teacher': ('egon',), ... , 'price': 20000}
print(linux.language)   # ['English']
print(linux.__dict__)   # {'teacher': ('eva',), ... , 'price': 20000}

       <2> 對象名的從新賦值是獨立的

python.language = 'English'
print(python.language)  # English
python.language = ['English']
print(python.language)  # ['English']
print(python.__dict__)  # {'teacher': ('egon',), ... ,'price': 20000, 'language': 'English'}
print(linux.language)   # ['Chinese']
print(linux.__dict__)   # {'teacher': ('eva',), ... , 'price': 20000}

(3)應用舉例

  需求:建立一個類,每實例化一個對象就記錄下來最終全部的對象共享這個數據

class Person:
    count = 0
    def __init__(self,name):
        self.name = name
        Person.count += 1
n1 = Person('gxx')
print(n1.count) # 1
n2 = Person('xcc')
print(n1.count) # 2
print(n2.count) # 2
n3 = Person('xcc')
print(n1.count) # 3
print(n2.count) # 3
print(n3.count) # 3
View Code

7. 認識綁定方法

# 函數 func
def func():
    pass
print(func) # <function func at 0x000001FA4DC7F0D0>

# 類中的方法 Foo.func
class Foo:
    def func(self):
        print('func類裏')
f1 = Foo()
print(Foo.func) # <function Foo.func at 0x000001FA4DC7F2F0>

# 對象調用方法的時候纔有綁定方法
print(f1)   # f1 <__main__.Foo object at 0x000001E57FE9E358>
print(f1.func)     # f1對象的綁定方法<bound method Foo.func of <__main__.Foo object at 0x000001FA4DC7E358>>
# 把對象f1以self的形式傳到方法中

8. 組合

組合:(面向對象的一種用法)

  一個對象的屬性值是另外一個類的對象

class Dog:
    def __init__(self,name,aggr,blood,kind):
        self.name = name
        self.aggr = aggr
        self.blood = blood
        self.kind = kind
    def bite(self,person):
        person.blood -= self.aggr

class Person:
    def __init__(self,name,aggr,blood,sex):
        self.name = name
        self.aggr = aggr
        self.blood = blood
        self.sex = sex
        self.money = 0

    def attack(self,dog):
        dog.blood -= self.aggr

    def get_weapon(self,weapon):
        if self.money >= weapon.price:
            self.money -= weapon.price
            self.weapon = weapon
            self.aggr += weapon.aggr
        else:
            print('餘額不足,請充值')

class Weapon:
    def __init__(self,name,aggr,njd,price):
        self.name = name
        self.aggr = aggr
        self.njd = njd
        self.price = price

alex = Person('alex',1,10,'m')
jin = Dog('金老闆',1000,500,'td')
w = Weapon('打狗棒',100,3,998)

alex.attack(jin)    # alex打了一下jin
print(jin.blood)    # 499

alex.money += 1000
alex.get_weapon(w)
print(alex.weapon)  # <__main__.Weapon object at 0x000001C38FC64B70>
print(jin.blood)    # 499

alex.attack(jin)    # alex用武器打了一下jin
print(jin.blood)    # 398
人狗大戰(有武器)
from math import pi
class Circle:
    def __init__(self,r):
        self.r = r
    def zc(self):
        return 2*pi*self.r
    def mj(self):
        return pi*self.r*self.r

class Ring:
    def __init__(self,outside_r,inside_r):
        self.outside_c = Circle(outside_r)
        self.inside_c = Circle(inside_r)

    def area(self):
        return self.outside_c.mj() - self.inside_c.mj()
    def perimeter(self):
        return self.outside_c.zc() + self.inside_c.zc()

ring = Ring(20,10)
print(ring.area())
print(ring.perimeter())
用組合實現:計算圓環的面積和周長
# 用組合實現:建立老師類,生日類,課程類,老師有生日,有課程信息

class Course:
    def __init__(self,cname,price,time):
        self.cname = cname
        self.price = price
        self.time = time
class Birthday:
    def __init__(self,year,month,day):
        self.year = year
        self.month = month
        self.day = day
class Teacher:
    def __init__(self,tname,sex,age,courseinfo,birth):
        self.tname = tname
        self.sex = sex
        self.age = age
        self.birth = birth
        self.course = courseinfo

b = Birthday(1996,7,18)
c = Course('Linux',2000,'2 days')
t = Teacher('xc','f',22,c,b)
print('老師姓名:' + t.tname)    # 老師姓名:xc
print(t.birth.year) # 1996
print('課程價格:' + str(t.course.price))    # 課程價格:2000
組合應用實例

 

 

借鑑:http://www.cnblogs.com/Eva-J/articles/7293890.html#_label1

相關文章
相關標籤/搜索