04-python中的面向對象編程-01

04-python中的面向對象編程-01

概念引入

首先面向對象編程 不是在python 中有,幾乎大部分的高級編程語言都是支持的。 面向對象編程 是一種編程思想,是一種寫代碼的一種思維, 這裏 我們就以python語言爲例 來介紹 什麼是 面向對象編程 。

說到面向對象編程,就要提到面向過程編程 這是兩種編程思想。

面向過程 一般比較好理解,比如 我要實現一個功能,函數 。我首先 就要知道 我第一步 要做什麼,第二步做什麼 ,第三步做什麼,最後做什麼。

舉個例子:

比如我每天早上 去上班,我需要怎麼做呢?

第一 我要早早的先起牀,雖然我很懶,但是還是要起來。
第二 我要開始準備洗漱吃飯,
第三 我要去公交站臺。
第四步  等車,然後上車,
第五步  等指定站臺下車,步行到公司。

上面的思考問題的過程 其實 就是 面向過程一種思考模型, 按照步驟,一步 一步 最後完成 任務。

根據上面的思考,我們很容易寫出來 下面的代碼,清晰流暢。沒有任何問題。

# -*- coding: utf-8 -*- 
import time


def go_office():
    """
    比如我每天早上 去上班,我需要怎麼做呢?

    第一 我要早早的先起牀,雖然我很懶,但是還是要起來。
    第二 我要開始準備洗漱吃飯,
    第三 我要去公交站臺。
    第四步  等車,然後上車,
    第五步  等指定站臺下車,步行到公司。
    :return:
    """

    print("我要早早的先起牀,雖然我很懶,但是還是要起來。")
    time.sleep(1)

    print("我要開始準備洗漱吃飯")
    time.sleep(1)
    print("我要去公交站臺。")
    time.sleep(1)

    print("等車,然後上車,")
    time.sleep(1)

    print("等指定站臺下車,步行到公司")
    time.sleep(1)


if __name__ == '__main__':
    go_office()

下面 來談談 面向對象 的思考方式 ,

在面向對象的編程思想的方式中 ,是這樣 思考的,我要去 到公司,我要怎麼做呢? 我需要有一輛車,我啓動車開車到公司。 或者 是 我需要有輛 公交車,帶我去公司去。 就這樣, 這就是面向對象 要思考的事情。

這裏 可以 把 我, 公司, 一輛車 , 公交車 這樣的名詞 ,在面向對象的世界裏面,這些都可以稱作一個叫 的一個東西。

在python中如何定義一個類呢?

只要一個關鍵字 class定義一個類

class Frank:
    pass

上面的方法,定義了一個類 ,只是這個類就只有一個類名。好,現在 開始 按照面向對象的方法,來實現 去公司這個操作。

# -*- coding: utf-8 -*- 
import time


class Car:
    """
    出租車
    """
    pass

    def start(self):
        time.sleep(1)
        print("開車 去公司")


class Bus:
    """
    公交車
    """

    def start(self):
        time.sleep(1)
        print("做公交 去公司")
        

class Frank:
    bus = Bus()

    pass

    @classmethod
    def go_office(cls):
        cls.bus.start()


if __name__ == '__main__':
    # go_office()

    Frank.go_office()

這裏 我定義了一個類 Car, Bus 這些類中 有一個方法 start , 還有一個Frank 類 這個裏面 有一個 Bus 類創建的一個對象bus , 然後 在 Frank 類中 有一個 go_office 方法, 這個方法 完成了 Frank 去公司這個操作。

這個例子可能 沒有那麼恰當 來解釋清楚 面向對象 和麪向過程 這兩種編程思想 的 好處,或者缺點。

我在來舉個例子 我感覺相對好一些來說明這個問題。

那麼如何面向對象編程呢?

面向過程面向對象 的一些思考過程?

假如 現在要求一個四邊形的周長,知道四個點座標,來求 這個四邊形的周長

只要把 四個點 兩個點之間的距離 算出來,然後相加,就可以了, 假設有以下 4個點 ,

在 square 的list 中,好 很快 就能寫好了代碼。如下

square = [(1, 1), (1, 2), (2, 2), (2, 1)]



def distance(p1, p2):
    return math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)


def perimeter(polygon): # polygon  多邊形
    perimeter = 0
    points = polygon + [polygon[0]]
    # print(f'{points}')
    for i in range(len(polygon)):
        print(f"{i},{points[i]},{points[i+1]}")
        perimeter += distance(points[i], points[i+1])
    return perimeter

perimeter(square)  # 4 

我們用面向 對象思想來思考

首先思考 求周長, 首先 計算四個點之間的距離, 然後 把邊長加起來就可以了。 那我們 可不可以,把點這個 東西 抽象 出來作爲一個類呢?

記住面對對象 編程 首先 要思考 在完成一個任務裏面 可以抽象出一個,然後用這個類 來完成 對數據的操作。

首先 我想把 點 這個 東西 可以抽象一個類,這個類裏面有 一個座標(x,y) , 然後 可以通過這個類 來計算 另一個點的距離, 其實 就是 剛剛寫的 求距離的函數 。

我們還要 思考 求周長 能不能 想辦法 抽象一個類出來呢, 如果你想不到 也沒有關係,其實可以抽象 一個 多邊形的類, 然後 由這個多邊形 來計算周長,這樣計算周長 就被封裝在 類中了。

看下面的例子:

import math


class Point:

    def __init__(self, x=0, y=0):
        self.reset(x, y)

    def move(self, x, y):
        self.x = x
        self.y = y

    def reset(self, x, y):
        self.x = x
        self.y = y

    def cal_distance(self, point):
        """
        求兩點之間的距離
        :param point:
        :return:
        """
        return math.sqrt((self.x - point.x) ** 2 + (self.y - point.y) ** 2)



class Polygon:
    def __init__(self):
        self.vertices = []

    def add_point(self, point):
        self.vertices.append(point)

    def perimeter(self):
        perimeter = 0
        points = self.vertices + [self.vertices[0]]
        for i in range(len(self.vertices)):
            perimeter += points[i].cal_distance(points[i + 1])
        return perimeter


if __name__ == '__main__':
    square = Polygon()

    square.add_point(Point(1, 1))
    square.add_point(Point(1, 2))
    square.add_point(Point(2, 2))
    square.add_point(Point(2, 1))

    ret = square.perimeter()

    print(f"{ret}")

Polygon 通過這個類 ,然後添加 point , 然後添加 perimeter 這個方法 。 這樣寫 其實 就是 把 面向過程 寫的 代碼 放在了 一個類中, 然後通過類中的一些 數據,然後通過實現方法來操作數據,最後 獲取結果。

上面的結果 和上面面向過程的結果是一樣的。

你可能有疑問了? 面向對象的寫法 ,把代碼寫多了,沒有什麼呀?

其實不然, 其實在寫代碼,最終要給你人來看的, 後期要考慮維護成本。面向對象 的方式 首先 本身 就是具有描述行爲的,比如 Point 類,本身代表了一個點,大家一個就能知道。

但是 如果按照面向過程中 定義一個list square = [(1, 1), (1, 2), (2, 2), (2, 1)] 我相信 如果過了一個月後 ,你再看 square 這個東西,你可能不理解 我這裏寫的 元祖 裏面的數字 代表什麼意思?

看到了嗎, 這就是區別,在面向對象的思想中 代碼的可讀性 更強,可維護更強。

python3中面向對象編程

通過上面的例子 你應該大概理解了面向對象思考過程。 對象 其實就是一個封裝, 對象 是 數據和行爲的一個集合,對象中的屬性 我一般喜歡叫數據,方法 就是用來來操作這些數據的。

對象 本身的行爲 叫 方法 。

以我舉個例子, 比如我現在 要封裝一個我這個類,我有一個方法 叫做飯,吃飯,還有一個方法叫游泳 。

我中還有一些屬性, 姓名 ,身高,體重。

class Person:

    def __init__(self, name, height, weight):
        self.name = name
        self.height = height
        self.weight = weight


person = Person(name='frank', height=165, weight=55)

這裏 就是通過 Person 來創建了一個對象 , Person(name='frank', height=165, weight=55) 這裏 的意思 就是 調用了 __init__ 方法 , 把三個屬性拷貝到了 person 的對象上面。

>>> person = Person(name='frank', height=165, weight=55)
>>> person.name
'frank'
>>> person.height
165
>>> person.weight
55

現在 你已經掌握瞭如何創建一個對象的方法。 你可能 會有疑問 爲啥 __init__() 方法裏面 爲啥會有self 參數,其實這個self 就是你將來 賦給的那個對象,這個self 你就可以這樣理解。 這裏 self 就相當於 你創建每創建一個新的對象,它就會指向這個對象。

person = Person(name='frank', height=165, weight=55) 比如這裏 self 就代指 person .

現在 來繼續實現一些方法

這裏只是舉例, 假設 eat 後 我體重會重, 游泳後,我體重會變輕。

class Person:

    def __init__(self, name, height, weight):
        self.name = name
        self.height = height
        self.weight = weight

    def cook(self):
        print(f"{self.name} is cooking")

    def eat(self):
        print(f"{self.name} is eating")
        self.weight = self.weight + 2

    def swim(self):
        print(f"{self.name} is  swimming")
        self.weight = self.weight - 1

>>> person.name,person.height,person.weight
('frank', 165, 55)
>>> person.cook()
frank is cooking
>>> person.eat()
frank is eating
>>> person.weight
57
>>> person.eat()
frank is eating
>>> person.weight
59
>>> person.swim()
frank is  swimming
>>> person.swim()
frank is  swimming
>>> person.weight
57

看上面的例子 ,當我吃飯的 時候 體重就會變重,游泳體重就會下降。這就是 面向對象 編程。

類和對象的關係,區別是什麼?

類 是用來 描述對象的。 它們就像用來創造對象的藍圖。 類相當於 是一個 模板 這個模板來創建一個對象。

類是對象的一個抽象,對象 就是一個具體的類,對象 就是由類 創建出來的。

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

p = Person(name='frank')
lily = Person(name='lily')

上面 定義Person 類,然後 由類 生成一個對象 p 和一個對象 lily 。 這一個對象 創建了兩個對象。

程序員 就是 每天都要面對很多對象,整天和這些對象打交道。

對象隨時有,只要你肯new。

你看程序員 沒有對象是不可能的,每天都和很多對象打交道。

簡單總結:

我們通過方法 來實現不同的功能,屬性 就是 對象中的一些 數據, 通過 方法 可以操作這些數據,來完成一些操作 這就是面向對象編程。

面向對象編程的好處 有哪些呢?

第一代碼比較清晰,通過名稱 大概知道 是做什麼。

第二 代碼 複用性更強, 因爲 類是可以繼承的。(以後會講到)

第三 更加 方便的維護 一些比較大的項目。

總結

​ 這篇 文章 主要簡單介紹了面向對象的基礎知識,瞭解面向對象思想。之後我會在寫一下 更好的使用面向對象的思想 進行編程 。 好了,有了這篇文章,你可以嘗試一下 把一些函數 變成一個類中的方法,改成面向對象的代碼。然後來感受一下,不同的編程方法。

分享快樂,留住感動. 2020-04-20 12:00:19 --frank
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章