面向對象 編程及面向對象三大屬性:封裝 繼承 多態

面向對象

面向對象(Object Oriented,OO)是軟件開發方法。面向對象的概念和應用已超越了程序設計和軟件開發,擴展到如數據庫系統、交互式界面、應用結構、應用平臺、分佈式系統、網絡管理結構、CAD技術、人工智能等領域。面向對象是一種對現實世界理解和抽象的方法,是計算機編程技術 [1] 發展到一定階段後的產物。
早期的計算機編程是基於面向過程的方法,例如實現算術運算1+1+2 = 4,通過設計一個算法就可以解決當時的問題。隨着計算機技術的不斷提高,計算機被用於解決越來越複雜的問題。一切事物皆對象,通過面向對象的方式,將現實世界的事物抽象成對象,現實世界中的關係抽象成類、繼承,幫助人們實現對現實世界的抽象與數字建模。通過面向對象的方法,更利於用人理解的方式對複雜系統進行分析、設計與編程。同時,面向對象能有效提高編程的效率,通過封裝技術,消息機制可以像搭積木的一樣快速開發出一個全新的系統。面向對象是指一種程序設計範型,同時也是一種程序開發的方法。對象指的是類的集合。它將對象作爲程序的基本單元,將程序和數據封裝其中,以提高軟件的重用性、靈活性和擴展性。
起初,“面向對象”是專指在程序設計中採用封裝、繼承、多態等設計方法。
面向對象的思想已經涉及到軟件開發的各個方面。如,面向對象的分析(OOA,Object Oriented Analysis),面向對象的設計(OOD,Object Oriented Design)、以及我們經常說的面向對象的編程實現(OOP,Object Oriented Programming)。
面向對象的分析根據抽象關鍵的問題域來分解系統。面向對象的設計是一種提供符號設計系統的面向對象的實現過程,它用非常接近實際領域術語的方法把系統構造成“現實世界”的對象。面向對象程序設計可以看作一種在程序中包含各種獨立而又互相調用的對象的思想,這與傳統的思想剛好相反:傳統的程序設計主張將程序看作一系列函數的集合,或者直接就是一系列對電腦下達的指令。面向對象程序設計中的每一個對象都應該能夠接受數據、處理數據並將數據傳達給其它對象,因此它們都可以被看作一個小型的“機器”,即對象。
面向對象的基礎語法

當一個類定義完成之後,要使用這個類來創建對象,語法格式如下:
對象變量 = 類名()

類的設計:

在程序開發中,要設計一個類,通常需要滿足以下三個要求:
1.類名 這類事物的名字,滿足大駝峯命名法
2.屬性 這類事物具有什麼樣的特徵
3.方法 這類事物具有什麼樣的行爲
例如:

小明今年18歲,身高1.75,每天早上要跑步,會去吃東西
小美今年17歲,身高1.65,小美不跑步,小美喜歡吃東西
類名:Person( )
屬性:name age height
方法:run( ) eat( )

一隻黃顏色的狗狗叫大黃
看見生人汪汪叫
看見家人搖尾巴
類名:Dog( )
屬性:color name
方法:shout( ) shake( )

需求:
小貓愛吃魚,小貓要喝水
"""
class Cat():
    def eat(self):
        print '小貓愛喝水'
    def drink(self):
        print '小貓要喝水'
tom = Cat()
tom.eat()
tom.drink()

# 需求:
# 小明今年18歲,身高1.75,每天早晨要跑步,會去吃東西
# 小美今年17歲,身高1.65,小美不跑步,喜歡吃東西
# Person()
# name
# age
# height
# run()
# eat()

面向對象的基礎語法:

定義簡單的類:
定義只包含方法的類:
class 類名:
def 方法1(self,參數列表):
pass
def 方法2(self,參數列表):
pass
當一個類定義完成後,要使用這個類來創建對象,語法格式如下:
對象變量 = 類名 ()

class Cat():
    def eat(self):
        print '%s 愛喝水 ' %self.name
    def drink(self):
        print '%s 要喝水'  %self.name
# 創建貓對象
tom = Cat()
tom.name = 'tom'
tom.eat()
tom.drink()
print tom
# addr = id (tom)
# print '%x' %addr
# %x:打印格式爲十六進制
# print '%d' %addr
# %d:打印格式爲十進制
mimi = Cat()
mimi.name = 'lazy_cat'
mimi.eat()
mimi.drink()
print mimi
addr1 = id(mimi)
print 'mimi的地址爲 %s' %addr1
lazy_cat2 = mimi
addr2 = id (lazy_cat2)
print 'lazy_cat2的地址爲 %s' %addr2

"""
在日常開發中,不推薦在類的外部給對象增加屬性
如果在運行時,沒有找到屬性,程序會報錯
"""


self的使用:

萬能說法:self 哪一個對象調用的方法,self就是哪一個對象的引用

    # self 哪一個對象調用的方法,self就是哪一個對象的引用
    def eat(self):
        print '%s 愛吃魚 ' % self.name

    def drink(self):
        print '%s 要喝水' % self.name


# 創建貓對象
tom = Cat()
tom.name = 'tom'
tom.eat()
tom.drink()
print tom
# addr = id (tom)
# print '%x' %addr
# print '%d' %addr
mimi = Cat()
mimi.name = 'mimi'
mimi.eat()
mimi.drink()
print mimi
# 創建出來的兩個貓對象沒有任何關係

面向對象初始化

初始化方法
我們現在已經知道了使用類名()就可以創建一個對象
當使用類名()創建對象時,python的 解釋器會自動執行以下操作:
1.爲對象在內存中分配空間–創建對象
2.調用初始化方法爲對象的屬性設置初始值–初始化方法(init(self))
這個初始化方法就是init方法,init時對象的內置方法
init方法是專門用來定義一個類具有哪些屬性的方法

class Cat():
    def __init__(self):
        print '__init__(self)是一種初始化方法'
        # 使用類名()創建對象的時候,會自動調用初始化方法'__init__(self)'
        self.name = 'fentiao'
        # self.屬性名 = 屬性的初始值,此時傳入的屬性名是固定的
tom = Cat()
print tom.name
Jimmy = Cat()
print Jimmy.name
# 固定的屬性名稱'fentiao'
class Cat():
    def __init__(self,new_name):
        # 傳入形參new_name
        print '__init__(self)是一種初始化方法'
        self.name = new_name
        # 在類中,任何方法都可以使用self.name
        print '%s 愛吃小魚' %self.name
tom = Cat('tom')
print tom.name
Jimmy = Cat('Jimmy')
print Jimmy.name

這裏寫圖片描述

內置方法

del方法:

在python中當使用類名()創建對象時,爲對象分配空間後,
會自動調用init方法;
當一個對象被從內存中銷燬前,會自動調用del方法

class Cat():
    def __init__(self,new_name):
        self.name = new_name
        print '%s 來了' %self.name
    def __del__(self):
        print '%s 被刪除了' %self.name
Tom = Cat('Tom')
print Tom.name

print '~~~~~'


class Cat():
    def __init__(self,new_name):
        self.name = new_name
        print '%s 來了' %self.name
    def __del__(self):
        print '%s 被刪除了' %self.name
Tom = Cat('Tom')
print Tom.name
del Tom
print '~~~~~'


str內置方法

在python中,使用python輸出對象變量,
默認情況下,會輸出這個變量引用的對象是由哪一個類創建的對象
以及在內存中的地址(十六進制)

如果在開發中,希望使用print輸出對象變量時,
能夠打印自定義的內容,就可以利用str這個內置方法

class Cat():
    def __init__(self,new_name):
        self.name = new_name
    def __str__(self):
        # 必須返回一個字符串
        return '我是一隻叫%s的小貓咪' %self.name

Tom = Cat('tom')
print Tom


“面向對象”是專指在程序設計中採用封裝、繼承、多態等設計方法:
下面我們就來學習封裝 繼承 多態
什麼是封裝 繼承 多態 ?
1.封裝
根據職責將屬性和方法封裝到一個抽象的類中定義類的準則
2.繼承
實現代碼的重用,相同的代碼不需要重複的編寫設計類的技巧
子類針對自己特有的需求,編寫特定的代碼
3.多態
不同的子類(這是之前提到的繼承的知識)對象調用相同的方法,產生不同的執行結果

封裝

1.封裝是面向對象編程的一大特點
2.面向對象編程的第一步 將屬性和方法封裝到一個抽象的類中
3.外界使用類創建對象,然後讓對象調用方法

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

    def __str__(self):
        return '我的名字是 %s,我的體重爲 %.2f' % (self.name, self.weight)

    def run(self):
        self.weight -= 0.5
        print '%s 每次跑步體重減少0.5公斤' % self.name
# 在對象的方法內部,是可以直接訪問對象的屬性
    def eat(self):
        self.weight += 1
        print '%s每次吃東西體重增加一公斤' % self.name


XX = Person('xiaoming', 75.0)
XX.run()
XX.eat()
XX.eat()
print XX

這裏寫圖片描述

擺放傢俱
需求:
1.房子有戶型,總面積和傢俱名稱列表
新房子沒有任何的傢俱
2.傢俱有名稱和佔地面積,其中
牀:佔4平方米
衣櫃:佔2平方米
餐桌:佔1.5平米
3.將以上三種傢俱添加到房子中
4.打印房子時,要求輸出:戶型,總面積,剩餘面積,傢俱名稱列表

設計思路:
1.創建了一個傢俱類,使用initstr兩個內置方法
2.準備了一個add_furniture 方法準備添加傢俱
3.使用房子類 創建了一個 房子對象
4.讓 房子對象 調用三次add_furniture 方法,
將三件傢俱以實參的形式傳遞到add_furniture

class Furniture:
    def __init__(self, name, area):
        #初始化方法
        self.name = name
        self.area = area

    def __str__(self):
        return '%s 佔地 %.2f' % (self.name, self.area)


# 創建傢俱
bed = Furniture('bed', 4)
print bed
chest = Furniture('chest', 2)
print chest
table = Furniture('table', 1.5)
print table


class House:
    def __init__(self, type, area):
        self.type = type
        self.area = area
        self.free_area = area
        # 剩餘面積
        self.fur_list = []
        # 傢俱名稱列表
    def __str__(self):
        return '房子戶型: %s' \
               '佔地面積:%.2f' \
               '剩餘面積: %.2f' \
               % (self.type, self.area, self.free_area)

    def add_furniture(self, fur_name, fur_area):
        print '添加 %s,面積爲 %s' % (fur_name, fur_area)
        # 1.判斷傢俱面積和剩餘佔地面積
        if fur_area > self.free_area:
            print '你的%s面積過大,無法添加' %fur_name
            return
            # 2.將傢俱名稱添加到列表中
        else:
            self.fur_list.append(fur_name)
        # 3.計算剩餘面積
        self.free_area -= fur_area


# 創建房子
my_home = House('兩室一廳', 100)
print House
# 添加傢俱
my_home.add_furniture('bed', 100)
my_home.add_furniture('chest', 2)
my_home.add_furniture('table', 1.5)
print my_home


士兵開槍問題:
1.士兵瑞恩有一把AK47
2.士兵可以開火(士兵開火扣動的是扳機)
3.槍 能夠 發射子彈(把子彈發射出去)
4.槍 能夠 裝填子彈 –增加子彈的數量
Soldier Gun
——– ———-
name model
gun bullet_count #子彈數量足夠多才能完成射擊的動作
——– ———-
init(self): init(self):
fire(self): add_bullet(self,count): #填充子彈的方法
shoot(self):

class Gun:
    def __init__(self, model):
        self.model = model
        self.bullet_count = 0

    def add_bullet(self, count):
        self.bullet_count += count

    def shoot(self):
        if self.bullet_count <= 0:
            print '%s子彈不夠' %self.model
            return
        self.bullet_count-= 1
        print '%s tututu 剩餘子彈數目爲 %d' % (self.model, self.bullet_count)


class Soliar:
    def __init__(self, name):
        self.name = name
        self.Gun = None
    def bullet_add(self,count):
        self.Gun.add_bullet()
    def fire(self):
        if self.Gun == None:
            print '%s 沒槍阿' % self.name
            return
        print '衝阿'

        self.Gun.shoot()


# 1.創建槍對象
ak47 = Gun('AK47')

# 2.創建士兵
ryen = Soliar('RYEN')
ryen.Gun = ak47
ryen.Gun.add_bullet(50)
ryen.Gun.shoot()
ryen.fire()
ryen.fire()
print ryen.Gun


這裏寫圖片描述
面向對象的三大屬性:
封裝:根據職責將屬性和方法封裝在一個抽象的類中
繼承:實現代碼的重用,相同的代碼不需要重複的寫
多態:不同的對象調用相同的方法,產生不同的結果,增強代碼的靈活度

單繼承

1.繼承的概念 語法 和 特點
概念:字類擁有父類的所有方法和屬性(子類只需封裝自己特有的功能屬性)
2.繼承的語法
class 類名(父類)
def 子類特有的方法
繼承的傳遞性:(爺爺 父親 兒子)
1.C類從B類繼承,B類從A類繼承
2.C類具有B類和A類的所有屬性和方法
子類擁有父類以及父類的父類中封裝的所有屬性和方法

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

    def drink(self):
        print '呵呵呵'

    def lue(self):
        print '略略略'


class Cat(Animal):
    def buy(self):
        print '買買買'


class DuolaAmeng(Cat):
    def play(self):
        print '玩玩玩'
DD = DuolaAmeng()
DD.lue()
DD.buy()
DD.drink()
DD.eat()
DD.play()

重寫父類

方法有兩種情況:

1.覆蓋父類的方法
2.對父類方法進行擴展

覆蓋父類的方法

如果在開發中,父類方法的實現和子類方法的實現完全不同,
就可以使用覆蓋的方式,在子類中重新編寫父類的方法

具體實現方式,就相當於在子類中定義了
一個和父類同名的方法並且實現
重寫之後,在運行時,只會調用子類的重寫方法,
而不會調用父類封裝的方法

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

    def drink(self):
        print '呵呵呵'

    def lue(self):
        print '略略略'


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


class DuolaAmeng(Cat):
    def speak(self):
        print '我可以說日語'
    def call(self):
        print '歐哈有'
dingdang = DuolaAmeng()
# 如果子類中,重寫了父類的方法
# 在運行中,只會調用子類中重寫的方法,不會調用父類的方法
dingdang.call()

繼承重寫擴展:

對父類的方法進行拓展
如果在開發中,子類的方法實現包含有父類的方法實現
(父類原本封裝的方法實現是子類方法的一部分就可以使用擴展方法)
1.在子類中重寫弗雷德方法
2.在需要的位置i使用 父類名.方法(self)來調用父類方法的執行
(使用父類名稱調用父類方法)
3.代碼其他的位置針對子類的需求,編寫子類特有的代碼實現

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

    def drink(self):
        print '呵呵呵'

    def lue(self):
        print '略略略'


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


class DuolaAmeng(Cat):
    def speak(self):
        print '我可以說日語'
    def call(self):
        print '歐哈有'
        Cat.call(self)
        print '卡哇伊'
kt = DuolaAmeng()
kt.call()


當出現重寫擴展被初始化需要先繼承父類初始化屬性,否則被覆蓋的屬性不能被子類繼承調用

class Bird:
    def __init__(self):
        self.hungry = True

    def eat(self):
        if self.hungry:
            print '餓了,然後吃飽飽了'
        else:
            print '不餓,謝謝'


class SongBird(Bird):
    def __init__(self):
        self.sound = 'lalala'
        Bird.__init__(self)

    def sing(self):
        print self.sound


# bird = Bird()
# bird.eat()

Little_bird = SongBird()
# Little_bird .eat() #繼承父類時會報錯,因爲被init初始化時覆蓋了,
# 此時需要在之前繼承父類的初始化
Little_bird.eat()
Little_bird.sing()


多繼承

子類擁有一個父類叫單繼承
子類可以擁有多個父類,並且具有所有父類的屬性和方法
例如:孩子會繼承自己父親和母親的特性

語法:
calss 字類名 (父類名1,父類名2…)
pass

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(B, A):
    pass
# 多繼承可以讓子類對象,同時具有多個父類的屬性和方法
# 當多繼承時,不同的父類中有相同的方法或屬性,子類繼承時,遵循其後跟的父類順序
# 誰在前,就用誰

c = C()
c.demo()
c.test()
class D(C):
    pass
D = C()
D.test()
D.demo()


3.多態

不同的子類(這是之前提到的繼承的知識)
對象調用相同的方法,產生不同的執行結果

class Dog(object):
    def __init__(self, name):
        self.name = name
        print '%s 會汪汪叫,自由自在玩' % self.name
    def game(self):
        print '%s 會玩 2048' % self.name


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

# 創建一個人對象
xiaolin = Person('xiaolin')
# 創建一個狗對象
wangcai = Zhuhegou('汪財')
# 汪財和人玩 汪財會玩王者榮耀

# wangcai = Dog('汪財')
# 汪財和人玩 汪財會玩2048
xiaolin.game_with_dog(wangcai)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章