Jex’s Note

PHP - 練習抽像、介面

程式碼 :

header('Content-Type: text/html; charset=utf-8');

/**
 * 題目 :
 *      (1)有一台紅色休旅車跟藍色法拉利
 *      (2)有前進、後退、左轉、右轉,基本功能
 *      (3)有加速跟減速,法拉利性能較優異(法拉利加速跟減速單位都是20公里, 休旅車是10公里)
 *      (4)紅色休旅車是自排,極速是180公里(打檔的方法我省略它沒有做)
 *      (5)藍色法拉利是手排,極速是320公里
 *
 * 介面跟抽象的差異 :
 *      (1)介面不可以定義屬性,只可以定義方法,而且只能是public,否則會得到錯誤,
 *          如: "Fatal error: Access type for interface method Car::accelerate() must be omitted in"
 *      (2)抽象可以宣告public/protected/private方法及屬性
 *      (3)只要有一個方法宣告為abstract,類別就要宣告為abstract
 *      (4)抽象跟類別都不能實體化,代表著 :
 *          1. 抽象只能被繼承(一個類別只能繼承一個父類別)
 *          2. 介面只能被實作(一個類別可以實作很多介面)
 *
 * 做法 :
 *      (1)如果大家都會做一模一樣的事情,可以用抽象定義
 *          (例如 : 因為前進、後退、左轉、右轉,動作大家都是一樣所以我在抽象定義)
 *      (2)如果大家是做同一件事情,但做法有差異用介面定義
 *          (例如 : 加速跟減速因為車種的性能不一樣,所以我在介面定義)
 *      (3)封裝速度,設定上下限
 */


// 介面 - 車子
interface Car {

    public function accelerate($times);     // 加速
    public function decelerate($times);     // 減速
}

// 抽像 - 操作動作
abstract class Operate {

    public $name;
    public $color;
    protected $_transmission;   // 排檔(手、自排)
    private $_direction;        // 方向(左、右轉)
    private $_movement;         // 移動(前、後)
    abstract protected function _set_speed($speed);
    abstract public function get_speed();

    public function __construct()
    {
        echo "$this->name [$this->color] [$this->_transmission] 生產出來了! <br>";
    }

    /**
     * 前進
     *
     * @access  public
     * @return  null
     */
    public function move_forward()
    {
        $this->_movement = '前進';
        echo $this->name."前進了! <br>";
    }

    /**
     * 後退
     *
     * @access  public
     * @return  null
     */
    public function move_back()
    {
        $this->_movement = '後退';
        echo $this->name."後退了! <br>";
    }

    /**
     * 左轉
     *
     * @access  public
     * @return  null
     */
    public function turn_left()
    {
        $this->_direction = '左轉';
        echo $this->name."左轉了! <br>";
    }

    /**
     * 右轉
     *
     * @access  public
     * @return  null
     */
    public function turn_right()
    {
        $this->_direction = '右轉';
        echo $this->name."右轉了! <br>";
    }

    /**
     * 取得車子目前狀態
     *
     * @access  public
     * @return  null
     */
    public function get_status()
    {
        echo $this->name."目前狀態是 : $this->_movement $this->_direction";
    }
}

// 物件 - 休旅車
class Suv extends Operate implements Car {

    public $name = '<span style="color:red;">休旅車</span>';
    public $color = '紅';
    protected $_transmission = '自排';
    private $_speed = 0;

    /**
     * set速度變數(極速180)
     *
     * @access  protected
     * @param   int
     * @return  null
     */
    protected function _set_speed($speed)
    {
        $this->_speed += $speed;
        if ($this->_speed >= 180)
        {
            $this->_speed = 180;
        }
        elseif ($this->_speed <= 0)
        {
            $this->_speed = 0;
        }
    }

    /**
     * get速度變數
     *
     * @access  public
     * @return  int
     */
    public function get_speed()
    {
        echo ",目前時速是 : ".$this->_speed." km/h <br>";
        return $this->_speed;
    }

    /**
     * 加速
     *
     * @access  public
     * @param   int         $times 加速的次數
     * @return  null
     */
    public function accelerate($times = 1)
    {
        $this->_set_speed(10 * $times);
        echo $this->name."加速".(10 * $times)." km/h,目前時速是 : $this->_speed<br>";
    }

    /**
     * 減速
     *
     * @access  public
     * @param   int         $times 減速次數
     * @return  null
     */
    public function decelerate($times = 1)
    {
        $this->_set_speed(-10 * $times);
        echo $this->name."減速".(-10 * $times)." km/h,目前時速是 : $this->_speed<br>";
    }
}

// 物件 - 法拉利
class Ferrari extends Operate implements Car {

    public $name = '<span style="color:blue;">法拉利</span>';
    public $color = '藍';
    protected $_transmission = '手排';
    private $_speed = 0;

    /**
     * set速度變數(極速320)
     *
     * @access  protected
     * @param   int
     * @return  null
     */
    protected function _set_speed($speed)
    {
        $this->_speed += $speed;
        if ($this->_speed >= 320)
        {
            $this->_speed = 320;
        }
        elseif ($this->_speed <= 0)
        {
            $this->_speed = 0;
        }
    }

    /**
     * get速度變數
     *
     * @access  public
     * @return  int
     */
    public function get_speed()
    {
        echo ",目前時速是 : ".$this->_speed." km/h <br>";
        return $this->_speed;
    }

    /**
     * 加速
     *
     * @access  public
     * @param   int         $times 加速的次數
     * @return  null
     */
    public function accelerate($times = 1)     // 法拉利性能好, 所以加20
    {
        $this->_set_speed(20 * $times);
        echo $this->name."加速".(20 * $times)." km/h,目前時速是 : $this->_speed<br>";
    }

    /**
     * 減速
     *
     * @access  public
     * @param   int         $times 減速次數
     * @return  null
     */
    public function decelerate($times = 1)     // 法拉利性能好, 所以減20
    {
        $this->_set_speed(-20 * $times);
        echo $this->name."減速".(-20 * $times)." km/h,目前時速是 : $this->_speed<br>";
    }
}


// 建立物件
$ferrari = new Ferrari();
$suv = new Suv();

// 執行動作
$ferrari->move_back();
$suv->move_back();
$ferrari->accelerate(5);
$ferrari->accelerate();
$ferrari->move_forward();
$suv->accelerate(3);
$ferrari->decelerate(30);
$suv->decelerate(5);
$ferrari->turn_left();
$suv->turn_right();
$suv->accelerate(20);
$ferrari->accelerate(20);
$suv->decelerate();
$ferrari->decelerate(4);
$suv->decelerate(8);
$suv->turn_left();
$ferrari->turn_right();

// 顯示最後結果
$suv->get_status().$suv->get_speed();
$ferrari->get_status().$ferrari->get_speed();

結果 :

擷取.PNG

Comments