# 一邊寫 C++ Class 一邊了解 OOP 4 個概念

# **四個概念**

## **抽象（Abstraction）**

> Abstraction is selective ignorance.
> 
> – Andrew Koenig

從沒有任何 code 到生出一個 `Car` 的 class，我們想把車子抽象出以下東西：

* move(double t): 移動 t 秒
    

所以可以寫出這樣的 class

```cpp
struct Car final {
    Car() = default;
    ~Car() = default;
    
    void move(double t) {
        // 這行計算不算在抽象部分
        x_ += speed_ * t;
    }
    
    double x_ = 0;
    double speed_ = 60;
};
```

## **封裝（Encapsulation）**

> 確保物件狀態良好。

假如我們不希望使用者隨意調整車子的速度和位置，那我們**要把他 private 起來**，並且，我們**不希望 move 的時間是可以倒流的**。

```cpp
class Car final {
public:
    Car() = default;
    ~Car() = default;
    
    void move(double t) {
        if (t < 0) {
            throw std::runtime_error("t is negative");
        }
        x_ += speed_ * t;
    }

private:
    double x_ = 0;
    double speed_ = 60;
};
```

## **繼承（Inheritance）**

`Car2` 是一種 `Car`

```cpp
class Car {
public:
    Car() = default;
    virtual ~Car() = default;
    // ...
};

struct Car2 : public Car {
};
```

## **多型（Polymorphism）**

`CarLazy` 是一種 `Car` ，並且他會偷懶，只用一半的速度移動。

```cpp
class Car {
public:
    Car() = default;
    virtual ~Car() = default;

    virtual void move(double t) {
        if (t < 0) {
            throw std::runtime_error("t is negative");
        }
        x_ += speed_ * t;
    }

// 給繼承人使用
protected:
    double x_ = 0;
    double speed_ = 60;
};

class CarLazy : public Car {
public:
    void move(double t) override {
        if (t < 0) {
            throw std::runtime_error("t is negative");
        }
        x_ += speed_ * t / 2;
    }
};
```

# **參考**

* [OOP 物件導向的四個特性](https://coreychen71.github.io/posts/2019-10/oop/)
    
* [物件導向編程精要](https://www.csie.ntu.edu.tw/~htlin/course/foop15fall/doc/EssentialOOP.pdf)
