zuppachu / Joanne-s-Learning-Blog

程式導師實驗計畫第二期 之 Coding 學習紀錄。
2 stars 0 forks source link

[ MTR02 ] - Week 5-2:物件導向程式設計 #13

Open zuppachu opened 5 years ago

zuppachu commented 5 years ago

Week 5-2

1:07 分 week5 作業關於時區的問題 $conn->query("SET NAMES 'UTF8'"); $conn->query("SET time_zone = '+08:00'");

物件導向設計(Object-Oriented Programming)

中國叫法為『面向對象』。

為什麼要有OOP?

  1. 解決程式碼分散的問題。下列寫法很分散~
    
    // 隨意寫計算機 
    function setResult() {
    }

function appendResult() { }

function inputNumber() { }

function inputOperator() { }

document.querySelector('.number').addEventListener('click', function(){ inputNumber(document.querySelector('.number').innerText) })

document.querySelector('.operator').addEventListener('click', function(){ inputOperator(document.querySelector('.number').innerText) })

2. 把資訊集合再一起,可以更貼近現實生活真的樣貌,例如學生例子。
```js
const students = []
const studentScore = []
const studentName = []

{
    name:'peter',
    score: 100,
    height: '190',
}

物件導向最重要的兩概念:class (類別)與 instance(實體)

類別:像設計圖藍圖,定義有什麼東西、什麼 function 可以用? 舉例來說:蓋房子的建築藍圖,藍圖內規劃廚房、主臥室在哪?有幾間房間?

而根據藍圖所建造出來的房屋就是實體

同一個設計圖( 類別,class ) 可以 new (新建) 很多新的東西,他們都有共同的方法可以用。 new 出很多 instance ,每個 instance 都有他自己的資料。

名稱上的差異: 當 function 出現在 class 裡面時,稱呼為 method(方法) 在外面時,才稱為 function (函式)

<?php

class Dog {
    function hello() { //method 方法:一個叫 hello 的方法
        echo "I am dog";
    }
}
// 用 new 創建一隻狗
$dog = new Dog();
// 呼叫 dog 的 hello()方法
$dog->hello();

---
// a 是 Dog class 的實體
$a = new Dog();
$a -> hello();

?>

11:00 處 與第四週作業四很相似。主要是-> 在 php 裡面用.來字串拼接,所以改用->

PHP 中的 class

13:00 處,檔案名稱: class.php

public 是預設。但很少用 public,因為別人可以亂改內容。

封裝 Encapsulation

把整個細節都藏在 class 裡面,外面無法看見細節,向外呈現的東西都非常簡潔。

$a = new Dog(); // a 是一個物件,同時也是 Dog 的 instance $a->name = ', my name is Leo'; $a->hello(); // 語法不同,在JS 裡面是 a.hello() // 得 I am a dog, my name is Leo

$b = new Dog(); $b->name = ', my name is Boo'; $b->hello(); //讓 b // 執行這個的時候 this 就是 b的名稱 // 得 I am a dog, my name is Boo

?>

```js
// private
<?php
class Dog {
    //把 hello() 設成 public 的 function 
    private $name = 'default';
    public function hello() {  // method 方法
        echo $this->getHelloSentence();
    }
    private function getHelloSentence(){
        return ' I am a dog  ' . $this->name; // 存取自己實體的東西用 this
    }

    // setter
    public function setName($name){
        $this->name = $name;
    }

    // getter
    public function getName($name){
        return $this->name;
    }
}

$a = new Dog();
$a->name = ', my name is Leo';
$a->hello(); // JS 裡面是 a.hello()
// 得 I am a dog, my name is Leo

$b = new Dog();
$b->name = ', my name is Boo';
$b->hello(); // 執行這個的時候 this 就是 b的名稱
// 得 I am a dog, my name is Boo

?>

原因:

  1. 不想無意間被改到。
  2. 利用 gettersetter可以做檢查。
    
    ....

// setter :專設定變數 public function setName($name){ if ($name === 'fuck') return; //如果是髒話,不執行 $this->name = $name; }

// getter:回傳變數 public function getName($name){ return $this->name; } ...

> 其實上面的概念用法,在之前 Ajax 功課時已經寫過了=> new 關鍵字
```js
// 要一個新的 request
let request = new XMLHttpRequest();
// 送到哪去
request.open('GET', url, true);
// 加一個 callback function
request.onload = () => {
 ...
} 

// 最後把 request 送回去
request.send()

$a = new Dog('Leo'); //這樣可以先設定好初始化 $b = new Dog('Boo'); $a->hello(); $b->hello(); // 執行這個的時候 this 就是 b的名稱

?>


- 從讓別人如何看得懂的方式下手
```js
// 以計算機為例,他的 class 可能如下:
// class.php 檔案內
class Calculator {

}

const calculator = new Calculator()
calculator.input(1)
calculator.input('+')
calculator.input(3)
const result = calculator.getResult()
console.log(result)

JavaScript 內的 Class

  1. 沒有 function 可以用
  2. 也沒有 public/ priviate
  3. js 對於 class 得運用沒那麼完整支援。
    
    // class.js 檔案內

class Calculator { constructor(name) { this.name = name; } hello(){ console.log(this.name) } }

const calculator = new Calculator('my calculator') calculator.hello() //得 my calculaator

/ calculator.input(1) calculator.input('+') calculator.input(3) const result = calculator.getResult() console.log(result) /

- 計算機的 class 設定方式: 
```js
// ES6
class Calculator {
   constructor() {
       this.text = ''; 
   }
   input(str) {
      this.text += str
   }
  getResult() {
      return eval(this.text)
   } 
}

calculator.input(1)
calculator.input('+')
calculator.input(3)
const result = calculator.getResult()
console.log(result)

其實 javascript 內沒有 class 關鍵字, javascript 還是希望能夠維持他原有的方式,所以可以利用常見的 fucntion 來操作替代 class 語法。

// ES5
// constructor 建構子
function Calaculator(name) {
  this.name = name
  this.text  = ''
//上面兩行做的事情與 class Calaculator 前兩行做的事情一樣。
}

// 可利用 .prototype 語法 = method
Calculator.prototype.input = function (str) {
   this.text += str
}

Calculator.propotype.getResult = function() {
    return eval(this.text)
}

const calculator = new Calculator()

calculator.input(1)
calculator.input('+')
calculator.input(3)
const result = calculator.getResult()
console.log(result)

小結: 以上兩種寫法皆可。或許是 class 寫法比較好懂

繼承 Inheritance

48:24 處

// class.php 檔案

<?php
class Animal {
    public $name = 'default';

   //  初始化
   public function __construct($name) { //建構子
        $this->name = $name;

   }
   public function sayHello(){
        echo 'I am ' . $this->name;
   }

class Dog { 

    public $name = 'default';

   //  初始化
   public function __construct($name) { //建構子
        $this->name = $name;      
   }

   public function sayHello(){
        echo 'I am ' . $this->name;
   }

   public function run() {
       echo 'I am running';
   }
}

$a = new Animal ('Leo');
//得 I am Leo
$a->sayHello();

$a = new Dog('Leo');
$a->sayHello();
$a->run();

?>

狗也是一種動物,所以動物有的屬性,狗也會有。 可以改寫成 『繼承』,如下:

<?php
...

// extends 擴充、延伸。
// Dog 擴充 Animal 這個類別
class Dog extends Animal {
    public function run() {
        echo ' I am running';
    }
    public function sayHello(){ // override 複寫
        echo 'I am dog' . $this->name;
    }
    public function sayYoAndHello() {
        parent::sayHello();
        echo 'yo';
    }
}

$a = new Dog('Leo');
$a->sayYoAndHello();

?>

除了上述以外,還可以用 static 方法

靜態方法 Static vs 方法 Method

Class 本身也可以有 function 。這個好處是,這個東西本身不會被改變,然後是建立在 Dog 底下的 function

<?php
...

// extends 擴充、延伸。
// Dog 擴充 Animal 這個類別
class Dog extends Animal {
    public function run() {
        echo ' I am running';
    }
    public function sayHello(){ // override 複寫
        echo 'I am dog' . $this->name;
    }
    public function sayYoAndHello() {
        parent::sayHello();
        echo 'yo';
    }
    public static function test() {
        echo 'test' ;
    }
}

$a = new Dog('Leo');
$a->sayYoAndHello();
$a->test();
dog:: test //更好的呼叫方式

?>
class MentorProgramAPI {
    static $version = 1;
    public function getTwitchResult(){
    }
}

$api = new MentorProgramAPI();
$api->getTwitchResult();
echo MentorProgramAPI::$version;

// $api2 = new MentorProgramAPI();
// $api2->getTwitchResult();
// $api2->version;
// echo $api2->version;
// 建構子 constructor
class Animal {
    constructor(name) {
        this.name = name
    }
    hello() {
        console.log(this.name)
    }
}
const dog = new Animal('My dog')
dog.hello()

const cat = new Animal('My cat')
cat.hello()

多型 Polymorphism

老師說之後會補充

參考

同學超詳細的筆記 :)

JavaScript 物件介紹:內有詳盡介紹 初學者應知道的物件導向 JavaScript

補充資料

給OOP初學者的建議:先搞懂「資料跟行為在一起」就好,其它的慢慢來 物件導向基礎:何謂類別(Class)?何謂物件(Object)? 物件導向基礎:何謂類別(Class)?何謂物件(Object)? [解答] 我要學會 Java (二):物件導向其實很簡單 什麼是物件導向程式設計呢?

zuppachu commented 5 years ago

補充其他相關資源

Codecademy - Introduction to JavaScript : classes 單元

class Dog {
  constructor(name) {
    this.name = name;
    this.behavior = 0;
  } 
}

const halley = new Dog('Halley'); 
// Create new Dog instance
console.log(halley.name); 
// Log the name value saved to halley
// Output: 'Halley'

解釋:

  1. 創建一個新的叫 hally 的變數
  2. 利用一個 new keyword 創建一個新的 Dog 類別的實體
  3. new keyword 呼叫 建構子 constructor() 然後跑碼