# C++隨手筆記#5 >前一篇 [C++ 隨手筆記#4](https://hackmd.io/@Neroal/B1spnjXrU) [TOC] ## 類別Class ### 甚麼是類別 舊約聖經紀載,上帝花了七天創造世界,並且在第六天創造了人。而人類又分成了許多**人種**,男人、女人、小矮人、進擊的巨人....等等。我要說的是,這種分成不同人種的概念就類似於**類別class** 類別跟我之前提到的結構struct很像,但不同的地方是,**struct的屬性是預設為public,而class預設為private** ### 使用方法 創建方法為 **class** **類別命名** **{變數...}** ```c++ #include <iostream> #include <string> using namespace std; class Student { public: string name; float height; float weight; }; int main() { Student student = {"Neroal",179.7,65.0}; cout << student.name << student.height << student.weight << endl; system("pause"); } ``` ## 物件Object ### 甚麼是物件 舉上面的程式做例子,**Student**是我們定義的**類別**,而我們命名的**student**就是所謂的**物件** 到這邊如果你還是聽不懂甚麼是類別與物件,那我再舉個更實際一點的例子。假設我們定義車子是一個**類別**,那麼賓士、法拉利、保時捷...等等就是所謂的**物件** ```c++ Student student = {"Neroal",179.7,65.0}; ``` ## 實例instance ### 甚麼是實例 實例其實跟物件非常像,也可以說是同一個東西。我們可以舉個例子,**賓士是車子的一個instance** ## 方法method 方法我們可以解釋為兩種,一個是**類別方法**,例如:使用汽車的方法;而第二種是**實例方法**,例如:使用賓士的方法 ### 使用方式 例如下方範例 **student.GetName()** ,我們就可以取得學生的名稱,如果method在類別裡設定為private,則無法去取用 ```c++ #include <iostream> #include <string> using namespace std; class Student { public: string name; float height; float weight; public: void GetName() { cout << name << endl; } void GetHeight() { cout << height << endl; } void GetWeight() { cout << weight << endl; } }; int main() { Student student = {"Neroal",179.7,65.0}; student.GetName(); system("pause"); } ``` ## 繼承inheritance ### 甚麼是繼承 ![](https://i.imgur.com/uIGfR4r.png) 上面這張圖闡明了繼承的概念,蘋果和香蕉都屬於水果,我們就可以說香蕉和蘋果繼承了水果類別,也就是說水果屬於父類別,而香蕉、蘋果屬於子類別。但是蘋果可以屬於香蕉嗎?答案是**不行的**。下方我們將會把水果例子引入到程式之中讓大家更了解繼承之概念 ```c++ class 水果 { 種類 盛產季節 } class 橘子 : public 水果 { 橘子() { 種類:柑橘類 盛產季節:秋季 } } class 西瓜 : public 水果 { 西瓜() { 種類:瓜類 盛產季節:夏季 } } ``` 在範例程式中我們定義了水果類別,因為橘子跟西瓜都屬於水果,所以兩者皆可以直接繼承水果類別,使用水果的屬性,像是種類、盛產季節...等等。所以像是橘子等類別我們又可以稱做**衍生類別(derived class)**,而水果類別我們可以稱做**基礎類別(base class)** ```c++ class 橘子 : public 水果 ``` :::warning 切記要在繼承之類別前加上**public**宣告,否則會無法取用該類別之屬性 ::: ### 使用方式 ```c++ #include <iostream> #include <string> using namespace std; class fruit { public: string type; string season; fruit() { cout << "種類:" << type << endl; cout << "盛產季節:" << season << endl; } void Print() { cout << "種類:" << type << endl; cout << "盛產季節:" << season << endl; } }; class orange : public fruit { public: orange(string a,string b) { type = a; season = b; } }; int main() { orange blueorange = {"柑橘類","秋季"}; blueorange.Print(); system("pause"); } ``` 這邊我們拿橘子來當作範例(雖然我不喜歡吃橘子...),下方我們將程式的部分分成三段來講。 ```c++ class fruit { public: string type; string season; fruit() { cout << "種類:" << type << endl; cout << "盛產季節:" << season << endl; } void Print() { cout << "種類:" << type << endl; cout << "盛產季節:" << season << endl; } }; ``` 首先我們定義了水果類別,給予兩個屬性,種類和盛產季節...等等。並且創建了一個建構子與方法 ```c++ class orange : public fruit { public: orange(string a,string b) { type = a; season = b; } }; ``` 接著我們定義橘子類別,並且繼承水果類別。繼承之後我們就可以去設定水果類別的屬性。這裡的建構子參數,可以直接將外部輸入的參數引用到水果類別的屬性之中 ```c++ int main() { orange blueorange = {"柑橘類","秋季"}; blueorange.Print(); system("pause"); } ``` 最後就是簡單的創建物件,然後引用先前水果類別的**Print**方法,接著我們可以看下方的結果顯示 結果顯示 :tv: ![](https://i.imgur.com/cICwRPy.png) :::info 這邊會顯示出兩次是因為第一次是在創建橘子類別時,水果類別的建構子會先執行。但這時候還沒到參數傳入的部分,所以這時候印出來的type跟season會是空的。第二次是在我們使用 **blueorange.Print()** 方法 ::: >下一篇 [C++ 隨手筆記#6](https://hackmd.io/@Neroal/HyqcgXDSI) ###### tags: `C++` `class` `object`