HOME ABOUT CONTACT

C/C++教學: 第二十七課 - 類別(Class)的封裝(Encapsulation)

Rain December 7, 2024
Outline

1. 簡介

2. 封裝(Encapsulation)

簡介top

本篇介紹 C++ 最為重要的角色 - 類別(Class),它具有封裝(Encapsulation)、繼承(Inheritance)和多型(Polymorphism)的特性,且類別可附帶屬性(變數、結構或其他類別)和方法(函式)。

類別(Class)是 C++ 系統設計的關鍵,大家若想更進一步理解如何運用類別做好系統設計,可以搜尋 Design Pattern 關鍵字,有很多文獻可以做參考和練習,本篇主要先介紹類別的封裝(Encapsulation)。

那麼我們就先來看看類別的定義語法:


class Car {
    public:
        ...
    protected:
        ...
    private:
        ...
};
                        

封裝(Encapsulation)top

上例的語法中,我們定義了一個類別為 Car,在這個類別中,我們可以定義屬性或方法的存取權限,如範例中寫道的 public、protected 和 private,public 即是公開可存取的類別屬性或方法,protected 是只有類別自己或子類別可以存取的屬性或調用方法,private 則是類別自身才能存取的屬性或調用的方法。

這麼說可能有點難理解,我們可以直接看看下面範例:


class Car {
    public:
        int m_x;
    protected:
        int m_y;
    private:
        int m_z;
};

int main()
{
    Car car;
    std::cout << car.x << std::endl;
    std::cout << car.y << std::endl; // 編譯錯誤,成員 y 的存取權限為 protected
    std::cout << car.z << std::endl; // 編譯錯誤,成員 z 的存取權限為 private

    return 0;
}
                        

上例我們在類別 Car 中定義了三個成員,分別是 m_x、m_y、m_z (通常類別或結構的成員都會以 m_ 作為命名開頭,以方便辨識該變數為某個類別或結構的成員,而非某個區域或全域變數),並且各自定義為不同的存取權限,然後在主函式中宣告了一個 Car 類別的物件,並且直接存取並輸出顯示這三個成員的值。然而你會發現在編譯時就會出錯了,因為 y 和 z 各自的存取權限為 protected 和 private。

也就是說類別中這兩個成員並不能由外部(非類別本身)來做存取,這就是所謂的封裝(Encapsulation),它可以提供一層資料的保護。而 protected 存取權限則是衍生類別(子類別)也可以存取和調用的,這在之後介紹繼承時再一併說明。

那麼,如果我們想修改或存取這些被封裝的資料,可以怎麼做呢? 來看看下面範例:


class Car {
    public:
        int m_x;
        void setY(int y) { m_y = y; }
        void setZ(int z) { m_z = z; }
        int getY() { return m_y; }
        int getZ() { return m_z; }
    protected:
        int m_y;
    private:
        int m_z;
};

int main()
{
    Car car;
    car.m_x = 1;
    car.setY(2);
    car.setZ(3);
    std::cout << car.m_x << std::endl;
    std::cout << car.getY() << std::endl;
    std::cout << car.getZ() << std::endl;

    return 0;
}
                        

我們可以設計一套可公開調用的方法來設置或存取這些被封裝的資料,如上例中的 setY()、setZ() 和 getY()、getX() 函式。因此通常 public 多為設計一個介面,讓外部可以存取這個類別中的屬性,或是繼續往下執行類別私有不公開(private)的方法。

下一篇: 第二十八課 - 類別(Class)的繼承(Inheritance)


Last updated:

Related Article List

  1. C/C++教學: 第二十五課 - 列表(List)
  2. C/C++教學: 第二十六課 - 基於範圍的 for 迴圈(Range-based For Loop)
  3. C/C++教學: 第二十八課 - 類別(Class)的繼承(Inheritance)