1. 程式人生 > >面向物件程式設計(沒有物件如何程式設計!)(初步學習)

面向物件程式設計(沒有物件如何程式設計!)(初步學習)

說到程式設計,我們很容易想到兩種思想:

  • 面向物件程式設計
  • 面向過程程式設計

這兩者有什麼區別呢?

面向過程就是分析出解決問題所需要的步驟,然後用函式把這些步驟一步一步實現,使用的時候一個一個依次呼叫就可以了。
面向物件是把構成問題事務分解成各個物件,建立物件的目的不是為了完成一個步驟,而是為了描敘某個事物在整個解決問題的步驟中的行為

看完上面的你相信一定沒有什麼感覺,的確我們如果剛剛接觸程式設計的話,打打OJ上的水題大概率上是用不到面向物件程式設計思想的。那麼到底什麼是面向物件程式設計,而我們為什麼要學習呢?


那麼我們先來分析一下面向過程程式設計,C語言就是一個很好的例子。

結構化程式設計:
C語言使用結構化程式設計。
簡單來說,這種結構化程式演算法的組成部分就是:
程式=資料結構+演算法

  • 程式由全域性變數以及眾多相互呼叫的函式組成。
  • 演算法以函式的形式實現,用於對資料結構進行操作。

結構化程式設計的不足

  • 結構化程式設計中,函式和其所操作的資料結構,沒有直觀的聯絡

  • 隨著程式規模的增加,程式逐漸難以理解,很難一下子看出來:

    • 某個資料結構到底有哪些函式可以對它進行操作?
    • 某個函式到底是用來操作哪些資料結構的?
    • 任何兩個函式之間存在怎樣的呼叫關係?
  • 結構化程式設計沒有“封裝”和“隱藏”的概念。
    要訪問某個資料結構中的某個變數,就可以直接訪問,那麼當該變數的定義有改動的時候,就要把所有訪問該變數的語句招出來修改,十分不利於程式的維護、擴充

  • 難以查錯,當某個資料結構的值不正確時,難以找出到底是哪個函式導致的

  • 重用:在編寫某個程式時,發現其需要的某項功能,在現有的某個程式裡已經有了相同或類似的實現,那麼自然希望能夠將那部分程式碼抽取出來,在新程式中使用。

  • 在結構化程式設計中,隨著程式規模的增大,由於程式大量函式,變數之間的錯綜複雜,要抽取這部分程式碼,會變得十分困難

例如:我們計算一個長方形的面積(python)

a=int(input());
b=int(input());
print(a*b);

好,如果沒有任何註釋,也沒有我之前的“我們計算一個長方形的面積”這句話,我們看到這個程式碼是不是會有很多種猜測。我們可能會想到,這個程式是做兩數的乘法運算,當然你也可以想到這個是長方形的面積。
但是,如果程式變得複雜呢,在未來的程式中我們可以看到上萬條程式碼,上萬個函式以及上萬個變數。

綜上所述,結構化程式設計的思想在程式規模擴大的時候會出現大量問題,各種變數之間的關係沒有一個明面上的關係。(就像別人給你看他交的OJ題為什麼錯誤然後一堆註釋都不寫,當你看著那些i,a,b,c等我們無法看出其含義的變數時,你就要花費許多時間來找出他們的關係。)那麼如果是一個專案呢?當你接手別人做的專案後,看著一堆函式,一堆變數是不是很頭疼?


所以我們引入了面向物件程式設計的思想

那麼這裡就要提到大多數程式語言中的類與物件
那麼通過我們可以清晰的知道變數與變數之間的關係,以及某些函式的作用等等。對於我們寫程式碼非常有用呢!
那麼面向物件的程式又如何組成呢?
面向物件的程式= 類+類+……+類

  • 面向物件的程式設計方法:
    • 將某類客觀事物共同特點(屬性)歸納出來,形成一個數據結構(可以用多個變數描述事物的屬性);
    • 將這類事物所能進行的行為也歸納出來,形成一個個函式,這些函式可以用來操作資料結構(這一步叫“抽象”)。
  • 然後,通過某種語法形式,將資料結構和操作該資料結構的函式“捆綁”在一起,形成一個“類”,從而使得資料結構和操作該資料結構的演算法呈現出顯而易見的緊密關係,這就是“封裝”。
  • 面向物件的程式設計具有 抽象,封裝,繼承,多型四個基本特點。

採用面向物件的程式設計方法,我們首先考慮的不是程式該如何執行,而是應該考慮我們處理的東西是什麼。

例如:我們要實現對學生成績的處理。
對於這個問題,我們考慮的是 “東西” 就是學生,那麼我們就把這個“東西”抽象一下,將其變成一個物件
那麼這個物件呢具有許多特徵(這裡我們叫做屬性
例如:學號,姓名,各科成績,性別等等等。
然後,我們在生活中就需要對學生的各種特徵(屬性)進行各種方面的處理,這裡我們叫做——物件的方法
幹說無用,而且不好理解。
我們來舉個比較常見的例子吧:
依然是計算長方形的面積:

"""
Calculate Rectangle Area
"""

class Rectangle:
    Reccount = 0

def __init__(self, length, wide):
    self.length = int(input())
    self.wide = int(input())
    Reccount+=1

def PrintArea(self):
    print (self.length * self.wide)
    
a=Rectangle(1,1)
a.setvalue()
a.PrintArea()

這裡我們寫了一個長方形的類,其實我們就是將 長方形 抽象成一個物件,而這個物件擁有 length(長)還有wide(寬)這兩個屬性,然後我們對其進行計算面積就是一種操作,也就是方法
那麼這個程式是不是比上面那種乾巴巴的程式更加直觀呢?

我們可以清晰的知道 變數 a 的資料型別就是Rectangle,然後他的函式與之聯絡我們也可以清楚的從中看出來。
通過一個類,我們就可以輕鬆解決面向過程中的難題,是不是很棒呢!
當然你會說,我也可以不用類寫啊,我可以寫一些函式,然後名稱與之相關不就好了,然後各種屬性我可以用結構體寫嘛。
沒錯,我覺得的確是可以這樣!
所以,在絕大多數面向物件的程式設計軟體,例如C++,Java,python等當然不侷限於此!
那麼我們先說到這裡,另外的新功能我們再慢慢講。