1. 程式人生 > >python面向物件程式設計

python面向物件程式設計

###面向過程 面向過程與面向物件 面向過程 側重於怎麼做 1.把完成某一個需求的 所有步驟 從頭到尾 逐步實現 2.根據開發要求,將某些功能獨立的程式碼封裝成一個又一個函式 3.最後完成的程式碼,就是順序的呼叫不同的函式 特點: 1.注重步驟與過程,不注重職責分工 2.如果需求複雜,程式碼會變得很複雜 3.開發複雜專案,沒有固定的套路,開發難度很大

面向物件 側重於誰來做 相比較函式,面向物件是更大的封裝,根據職責在一個物件中封裝多個方法 1.在完成某一個需求前,首先確定職責–要做的事(方法) 2.根據職責確定不同的物件,在物件內部封裝不同的方法(多個) 3.最後完成程式碼,就是順序的讓不同的物件呼叫不同的方法 特點: 1.注重物件和職責,不同的物件承擔不同的職責 2.更加適合對複雜的需求變化,是專門應對複雜專案的開發,提供的固定套路 3.需要在面向過程的基礎上,再學習一些面向物件的語法

類與物件 類:是對一群具有相同特徵或行為的事物的一個統稱,不能直接使用(比如:飛機制造圖紙不能飛上天) 特徵:屬性 行為:方法 物件:由類創建出來的一個具體的存在,可以直接使用(用圖紙製造出來的飛機可以飛上天) 在程式開發中:應該先有類 再有物件

類的設計: 1.類名 這類事物的名字,滿足大駝峰命名法 大駝峰命名法 每一個單詞的首字母大寫 單詞與單詞只見沒有下劃線 2.屬性 這個類創建出的物件有什麼樣的特徵 3.方法 這個類創建出的物件有什麼樣的行為

語法:

建立一個類
class 類名:
        def 方法1(self):
                pass
        def 方法2(self):
                pass
建立物件: 
物件變數 = 類名()

同一個類可以建立不同的物件

例: 小貓愛吃魚,小貓要喝水 此處tom與lazy_tom都是由cat這個類建立,但是他們兩個在記憶體中的地址不一樣,說明不是同一個物件 這裡寫圖片描述

內建方法

初始化方法__init__:專門用來定義一個類具有哪些屬性和方法的

__del__方法:物件被從記憶體中銷燬前,會自動呼叫
希望物件在被銷燬之前再做一些事,可以考慮此方法

__str__方法:返回物件的描述資訊  print物件
希望使用print輸出物件變數時,能夠列印自定義內容,就可以利用此方法

生命週期: 一個物件從呼叫類名( )建立,宣告週期開始 一個物件的__ del __方法一旦被呼叫,生命週期就結束 在物件的生命週期內,可以訪問物件的屬性,呼叫物件的方法

init 方法 這裡寫圖片描述 str方法 這裡寫圖片描述 del方法與del關鍵字區別 這裡寫圖片描述 這裡寫圖片描述

私有屬性和私有方法 私有屬性和私有方法 私有屬性,私有方法是物件的隱私,不對外公開,外界以及子類都不能直接訪問 私有屬性,私有方法常用做一些內部的事情

應用場景 在實際開發中,物件的某些屬性或方法可能只希望在物件的內部使用,而不希望在外部被訪問到 私有屬性就是 物件不希望公開的屬性 私有方法就是 方法不希望公開的方法 定義方法 在定義屬性或者方法時,在屬性名或者方法名前增加兩個下劃線,定義的就是私有屬性或方法

私有屬性,外界不能直接訪問 這裡寫圖片描述 私有方法,外界不能直接呼叫 這裡寫圖片描述 如果想呼叫私有方法和訪問私有屬性,可以再公有方法中呼叫私有方法及列印私有屬性 這裡寫圖片描述

面向物件三大特徵

封裝

封裝:根據職責將屬性和方法封裝到一個抽象的類中 1.封裝是面向物件變成的一大特點 2.面西那個物件程式設計的第一步,將屬性和方法封裝到一個抽象的類中(為什麼說是抽象的,因為類不能直接使用) 3.外界使用類建立物件,然後讓物件呼叫方法 4.物件方法的細節都被封裝在類的內部

class Person:
    def __init__(self,name,weight):
        # 初始化方法中增加兩個引數由外界傳遞
        # self.屬性 = 形參
        self.name = name
        self.weiget = weight
    def __str__(self):
        return '我叫%s 體重 %.2f' % (self.name,self.weiget)
    def run(self):
        print '%s愛跑步' % self.name
        # 在物件方法的內部,是可以直接訪問物件的屬性
        self.weiget -= 0.5
    def eat(self):
        print '%s吃東西' % self.name
        self.weiget += 1

xiaoming = Person('小明',75)
xiaoming.run()
xiaoming.eat()
xiaoming.eat()
print xiaoming

xiaomei = Person('小美',45)
xiaomei.eat()
xiaomei.run()
print xiaomei

這裡寫圖片描述

例: 擺放傢俱 房子有戶型,總面積和傢俱名稱列表 新房子沒有任何傢俱 傢俱由名字和佔地面積 床佔4平米 衣櫃佔2平米 餐桌佔1.5平米 1.將以上三件傢俱新增到房子中 4.列印房子時,要求輸出:戶型,總面積,剩餘面積,傢俱名稱列表

被使用的類應該先開發

class HouseItem:
    def __init__(self,name,item_area):
        self.name = name
        self.item_area = item_area
    def __str__(self):
        return '[%s] 佔地%.2f' % (self.name,self.item_area)

class House:
    def __init__(self,house_type,house_area):
        # 需要從外界傳遞進來的引數
        self.house_type = house_type
        self.house_area = house_area
        # 剩餘面積(新房子無傢俱,剩餘面積等於總面積)
        self.free_area = house_area
        # 傢俱名稱列表
        self.item_list = []
    def __str__(self):
        return '戶型:%s\n總面積:%.2f[剩餘:%.2f]\n傢俱:%s' %(self.house_type,self.house_area,self.free_area,self.item_list)
    def add_item(self,item):
        print '要新增:%s' % item
        if item.item_area <= self.free_area:
            self.item_list.append(item.name)
            self.free_area -= item.item_area
        else:
            print '房子剩餘面積不足,無法新增傢俱'


# 建立傢俱物件
bed = HouseItem('bed',4)
chest = HouseItem('chest',2)
table = HouseItem('table',1.5)

# 建立房子物件
my_home = House('兩室一廳',80)

my_home.add_item(bed)
my_home.add_item(chest)
my_home.add_item(table)
print my_home

這裡寫圖片描述

繼承

繼承:實現程式碼的重用,相同的程式碼不需要重複的寫 分單繼承和多繼承

語法:

class 類名(父類):
        def 子類特有的方法

繼承的概念:子類擁有父類的所有屬性和方法 子類繼承自父類,可以直接享受父類中已經封裝好的方法 子類中應該根據自己的職責,封裝子類特有的屬性和方法 單繼承

class Animal:
    def eat(self):
        print '吃'
    def drink(self):
        print '喝'
    def run(self):
        print '跑'
    def sleep(self):
        print '睡'

class Cat(Animal):
    def call(self):
        print '喵'

class Hellokitty(Cat):
    def speak(self):
        print "你好"

#建立一個貓物件
cat = Cat()
cat.eat()
cat.drink()
cat.run()
cat.sleep()
cat.call()

# 建立一個hellokitty物件
kt = Hellokitty()
# 繼承的傳遞性,子類擁有父類的父類的所有屬性和方法
kt.eat()
kt.drink()
kt.run()
kt.sleep()
kt.call()
kt.speak()

這裡寫圖片描述

子類和父類,基類和派生類 由上面程式碼舉例: Cat類是Animal類的子類,Animal類是Cat類的父類,Cat從Animal類繼承 Cat類是Animal類的派生類,Animal類是Cat類的基類,Cat從Animal類派生

父類重寫 1.覆蓋父類的方法 如果子類中,重寫了父類的方法,在執行中,只會呼叫在子類中重寫的父>類方法而不會呼叫父類的方法

class Animal:
    def eat(self):
        print '吃'

    def drink(self):
        print '喝'

    def run(self):
        print '跑'

    def sleep(self):
        print '睡'


class Cat(Animal):
    def call(self):
        print '喵'


class Hellokitty(Cat):
    def call(self):
        print '歐尼醬'


kt = Hellokitty()
kt.call()

這裡寫圖片描述

2.擴充套件父類的方法 父類名.方法(self)

class Animal:
    def eat(self):
        print '吃'

    def drink(self):
        print '喝'

    def run(self):
        print '跑'

    def sleep(self):
        print '睡'


class Cat(Animal):
    def call(self):
        print '喵'


class Hellokitty(Cat):
    def call(self):
        print '歐尼醬'
        Cat.call(self)

kt = Hellokitty()
kt.call()

這裡寫圖片描述

3.初始化方法也是一種方法,需注意被覆蓋當呼叫

當呼叫bird.eat()時,由於子類覆蓋了父類初始化方法所以,判斷eat() 方法時沒有hungry這個屬性,導致報錯 這裡寫圖片描述 此時需在子類初始化方法下再次呼叫父類初始化方法

class Bird:
    def __init__(self):
        self.hungry = True
    def eat(self):
        if self.hungry:
            print '吃東西'
            self.hungry = False
        else:
            print '不吃'
class SongBird(Bird):
    def __init__(self):
        self.sound = 'squawk'
        # 此時需再次呼叫父類初始化方法
        Bird.__init__(self)
    def sing(self):
        print self.sound
bird = SongBird()
bird.sing()
bird.eat()

這裡寫圖片描述

繼承私有屬性和私有方法 class A: def init(self): # 在初始化方法中定義兩個屬性,一個共有屬性一個私有屬性 self.num1 = 100 self.__num2 = 200

    def __test(self):
        print '私有方法 %d %d' %(self.num1,self.__num2)

    def test(self):
        print '父類的公有方法 %d' % self.__num2
        self.__test()


class B(A):
    def demo(self):
        # 在子類的物件方法中,不能訪問父類的私有屬性
        # print '訪問父類的私有屬性%d' % self.__num2
        # 在子類的物件方法中,不能呼叫父類的私有方法
        # self.__test()
        self.test()

b = B()
b.demo()

這裡寫圖片描述

多繼承 繼承多個類的方法 多繼承時,當方法名重複時。繼承前面的, class A: def test(self): print ‘A------test 方法’ def demo(self): print ‘A------demo 方法’

class B:
    def test(self):
        print 'B------test 方法'
    def demo(self):
        print 'B------demo 方法'

# 多繼承時,當方法名重複時。繼承前面的,
class C(A,B):
    pass

c = C()
c.demo()
c.test()

這裡寫圖片描述

新式類和舊式(經典)類 object是python為所有物件提供的基類,提供有一些內建的屬性和方法,可以使用dir函式檢視 新式類:以object為基類的類,推薦使用 經典類:不以object為基類的類,不推薦使用

在python2.x中定義類時,如果沒有指定父類,則不會以object作為父類

多型

多型:以封裝和繼承為前提,不同的子類物件呼叫相同的方法,產生不同的執行結果

class Dog(object):
    def __init__(self, name):
        self.name = name

    def game(self):
        print '%s蹦蹦跳跳的玩耍!' % self.name


class Erha_dog(Dog):
    def game(self):
        print '%s飛到天上玩耍!' % self.name


class Person(object):
    def __init__(self, name):
        self.name = name

    def game_with_dog(self, dog):
        print '%s和%s快樂的玩耍!' % (self.name, dog.name)
        dog.game()

Person類中只需要讓狗物件呼叫game方法(這是子類的父類中封裝的方法),而不關心具體是什麼狗 game方法是在Dog父類中定義的 在程式執行時,傳入不同的狗物件的實參,就會產生不同的執行結果 在這裡插入圖片描述

在這裡插入圖片描述

靜態方法

通過 類名. 呼叫靜態方法 不要建立物件,就可以直接使用 在這裡插入圖片描述

類屬性與類方法

類是一個特殊的物件—類物件 在程式執行的時候,類物件(建立例項物件的模板)在記憶體中只有一份 通過它可以創建出和很多個物件例項 除了封裝例項的屬性和方法外,類物件還可以擁有自己的屬性和方法 1.類屬性 就是給類物件定義的屬性,通常用來記錄與這個類相關的特徵 類屬性不會用於記錄具以的物件特徵 在這裡插入圖片描述 2.類方法 類屬性就是正對類對性定義的 使用賦值語句在class關鍵字下方可以定義類屬性 類屬性用於記錄與這個類相關的特徵

類方法就是正對類物件定義的方法 在類方法內部就可以直接訪問類屬性或者呼叫其他類方法 在這裡插入圖片描述