筆記、物件導向 ( 程式導師實驗計畫 )


Posted by s103071049 on 2021-12-17

物件貼近現實生活的樣貌

為甚麼要有物件導向 ?

用 funct 的寫法,code 會很分散,因為最後還是要依靠各個 funct,但各個 funct 其實是散落在不同地方。以計算機小程式為例

如果還有其他功能,相同類型的 funct 可能就會被打散。code 散落各地但最後 call 一個 funct 做這些事情。

此外,沒有物件全部用陣列表達會變得非常麻煩,會變得像是一個一個變數分散開來。但有了物件,就可以將相關的屬性集合起來。

sum up

為甚麼要有物件導向

  1. 因為純用 funct,code 會散落各地
  2. 物件可以將相關屬性集合起來
    # 重要觀念

    ## 設計圖:class (類別)
    定義物件的長相,有什麼樣的內容,有什麼樣的 funct 可以使用

基本上在 class 裡面的 funct 我們稱呼為 method(方法)

透過 new 出一個 instance 將設計圖變成實體,然後存到變數 $dog 去。有了真的狗後就可以執行一些方法。

$dog 是 Dog 的實體。

因為 php 裡面 dot (.) 是做字串連接,所以要改成箭頭。


funct 前面還有不同的關鍵字,可以把它想成宣告方法,預設為 public,表示在哪裡都可以存取的到這個方法。

若改成 private,外面就沒辦法呼叫。所以為甚麼要寫一個外面沒辦法呼叫的 funct ? 這的東西我們叫他封裝

封裝 Encapsulation

將細節都藏到 class 裡面,那開出去外面的東西長相就會相對簡單。ie 將細節都隱藏到物件裡面,外面不需要知道這些細節只要 call 他就好了

首先,將 hello 設為 public funct,所以在外面就可以用 $a->hello();,但如果想在外面呼叫 $a->getHelloSentence(); 是無法得,因為他是 private

ie 開一個方法出去叫 hello,如果想要這個狗打招呼只要 call $a->hello();,你完全不需要知道他的底層如何實作。只要用,不需要知道細節,這就叫封裝。

$this 指的是現在狗的這個實體。

ex1

宣告一個變數,先加 private,ie 外面無法存取


如果將變數改成 public,外面可以正常存取


會輸出 I am leo

當我們將 $a->name = 'leo' 註解,會輸出 I am default

可以經由 public 的變數在外面改這些東西

若在裡面要存取自己的東西,就用 $this, $this 表示我現在的 instance,我輸出的是我現在 instance 的 name

一個設計圖可以產生多個東西,一個 class 可以產生出多個 instance,每個 instance 都有它自己的資料。

ex2

通常不會將東西設為 public,因為所有人都可以進行修改。

透過 setter funct,去專門設定變數
透過 getter 將我的東西吐回去



東西改成 public 外面也可以存取,為何要這麼麻煩 ?

第一、不想讓東西無意間被改動,只希望他透過這兩個 method 進行存取。getter, setter 可以做一些檢查,可以保證裡面東西不會被外面動到

Recall: AJAX request

瀏覽器提供 XMLHttpRequest 這個 class 給我用,因為需要製造出一個真的 request,所以需要 new 出一個 instance

此外,語意上更清楚、更好維護。

  • 我要一個新的 request
  • 要送到哪去
  • 加一個 cb funct / 將 response 讀回來
  • 將 request 送出

比起 sendRequest(method, url, callback)

ex3 - js 計算機

你要怎麼讓別人用這個東西著手,別人在麼 call 比較方便想。(與經驗值有關)

如果將 input 分成 inputNumber 與 inputOperator,還要讓去 call 的人決定是甚麼 type,比較麻煩

js 語法差別在沒有 funct 這些東西,也沒有 private / public 可以使用,他的支援其實相對沒這麼完整

初始化:constructor

通常在 new 一個物件出來時,我們會希望在初始化的同時傳一些資訊進去,ex: $a = new Dog('leo'); 這樣狗一出來就不用呼叫 setter funct。透過 constructor 進行接收,php 裡面會用兩個底線開頭

用 new 來 call funct,會執行到 __construct,然後就可以設定一些東西

ex:
把東西都集中在 DB 這個 class 裡面,所以要改任何相關的東西就去這裡面改就好了,透過集中管理讓 code 更好維護

有 construct 也有 destruct。當物件要關掉,要做甚麼善後的事情

QA

Object 與 instance 的差別 ? 可以把 object 想成一個 instance,new 出的 instance 就是一個物件,他是這個 class 的 instance。

有物件導向才有 this

this 指的是那個實體本身。

為甚麼需要 this ? 因為需要一個東西可以指到現在自己的 instance。this 通常會發生在 funct 裡面。

funct 一定要傳參數,才會知道要對甚麼東西做操作。但用物件導向,我們將 funct 變成只要傳一個參數就好了,傳她真正需要的參數。

因為我們將東西藏在裡面,裡面可以用 this 指射到我們現在指射到的這個 instance 這個物件,他的 conn 這個變數,就不需要顯示 ie 你沒有傳她會不知道要對甚麼東西做甚麼事情。有了 this 可以指射到我現在這個 conn

$conn->fetch_result($query)
function fetch_result($q) {
  $this->conn->mysql_fetch_result($q);
}

js 不是 new 出來的東西也有 this 可以用。所以他到底指向誰 ?

ex js 計算機

加上 eval 就會把我們裡面輸出的東西當作程式碼,eval(this.text)

示意:

繼承(Inheritance)

狗是動物,所以現在有 class 叫 animal,裡面就有 hello 這個方法。我們假設所有動物都會說話。

動物有的這些方法與屬性,狗也應該要有。因為狗也是一種動物。

繼承會繼承某個 class 裡面的所有東西。

但如果在狗有繼承的東東,就會出現覆寫

另外,this 在他底下全是共通的

如果上層用 private 會發生甚麼事情嗎 ? 他就只能給他自己存取,我在 Dog 找不到 this.name 這個東西,因為宣告 private 所以只有 Animal 能存取這個屬性

關鍵字除了 public, private 還有 protected,其中 protected 很像 private 只是繼承他的東西也可以使用,但仍然無法直接在外面使用,ie 從自己與其子孫看是 public,但從外面看是 private

php 透過 patent:: 可以存取到 parent 的方法,ex: 我的 parent 的 sayHello

js 透過 super 存取到 parent 的方法,ex: 輸入是三,但我讓他到 parent 是 3。對 input 這個 method 做小的改變

如果想改其中一小部分 code,就可以用繼承做這件事,保持他原有的特性又新加上一些東西

靜態方法:static

宣告 class 後需要 new 一個 instance 才能使用它裡面的這些 method。

加上 static 的關鍵字呼叫也可以

static 是說這個 method 他不是屬於 instance,他是屬於這個 class 的。所以比起下面黃色線的呼叫,他其實會 Dog::test()

要存取 class 會用冒號,箭頭 -> 是給 instance 用

class 本身也可以有一些 funct

靜態方法的好處是你這個東西他不會改變,他是建立在 class 底下而非 instance 底下。通常不會有甚麼資訊。有靜態 funct,也有靜態變數。

通常會存一些不會改到的資料,每個 instance 都會共用到的變數,就會宣告成 static,因為他不需要改。

ex1: call api

有沒有東西是不該放在 instance 裡面,而應該放在 class 裡面的呢 ?

第一種:靜態變數綁在 class 上面,這個變數永遠就只有一份。因為他是跟 class 走的

第二種:將變數放在 instance 裡面,不同的 instance 不同的記憶體位置

ex2: time zone

如果不合理,你已經 new 了也有點怪

希望在 new 之前就先檢查過

JS 的 class 與 prototype

js 裡面沒有 class 這個關鍵字,他沒有 class 語法。可以使用是因為底層用其他東西實做

js 希望還是能維持這樣的語法,如果 Calculator 不是 class 他可以是甚麼 ? 他可以是 funct,用 new 呼叫這個 funct,這個 funct 就變成建構子的作用

兩邊是一樣的,只是有了 class 之後會有一個叫做 constructor 的 funct

js 希望可以用 instance 的方法,是跟其他物件導向語言差不多的。他透過 funct 去實作。所以當我用 new 接一個 funct 的時候,他回傳出來的 calculator 就是 Calculator 這個 funct 或說是這個 class 的 instance

如果要加一些 method 的話,他會透過 prototype 的寫法


#物件導向 #Object oriented program #OOP







Related Posts

DOM 的事件傳遞機制與事件代理

DOM 的事件傳遞機制與事件代理

[Day 03] - Vault 的基本操作

[Day 03] - Vault 的基本操作

[1] Python 3 簡介與安裝

[1] Python 3 簡介與安裝


Comments