什麼是物件導向,差別在哪裡
用一句話來形容就是
資料與方法的群組化再群組化
如果說編程是解放
繁瑣與重複的工作
,那麼物件導向就是解放編程的繁瑣與重複的工作
下面讓我用簡單的群組概念來解釋如何解放繁瑣的工作,當然~實際上物件導向不只如此,舉例只是這個海灘的中的其中一粒沙子,但是這已經有足夠強大的功能與便利性了。
讓我們看看一個單向鍊結的實例,下面是一個用C語言實做的例子
函式
// 資料結構
typedef struct node Node;
struct node {
int data;
Node* next;
};
// 初始化節點
Node* link_init(int num) {
Node* n = (Node*)malloc(sizeof(Node));;
n->data = num;
n->next = NULL;
return n;
}
// 尾端新增節點
Node* link_append(Node* node, int num) {
node->next = link_init(num);
return node->next;
}
// 插入節點
void link_insert(Node* node, size_t idx, int data){
// 旗標(插入點的前一個)
for(unsigned i = 0; i < idx; ++i) {
node = node->next;
}
Node* temp = node->next;
node->next = link_init(data);
node->next->next = temp;
}
操作範例
// 新增鏈結
Node* head = link_init(-1);
Node* tail = head;
// 新增節點
tail = link_append(tail, 1);
tail = link_append(tail, 2);
tail = link_append(tail, 3);
// 插入節點
link_insert(head, 1, 0);
// 查看節點
for(Node* n = head->next; n; n=n->next) {
printf("%d, ", n->data);
} printf("\n");
// 刪除鏈結
link_delete(head);
head=NULL;
return 0;
在這個例子裏面可以看到有三件繁瑣的事情
- 每一個函式呼叫都需要引入 Node*
- 為了方便識別函式是對屬於誰的,名稱帶前缀名
- 結束之後自己要記得 delete
由於這是一個簡單的範例所有只有幾個函式看起並不多餘,如果這個鏈結陣列裝的東西不只是int可能會需要很多個函式來操作處理,這時候每一個函式參數都要帶一個 Node* 就顯得有些多餘。
那物件導向是怎麼優化這件事情的呢,讓我們來看一下物件導向的寫法。
函式
struct Node_class{
// 資料結構
struct Node {
int data;
Node* next;
} *node, *tail;
// 初始化
Node_class(){
node = init(-1);
tail = node;
}
// 自動刪除鏈結
~Node_class(){
del();
}
// 初始化節點
static Node* init(int num) {
Node* node = (Node*)malloc(sizeof(Node));;
node->data = num;
node->next = NULL;
return node;
}
// 尾端新增節點
void append(int num) {
tail->next = init(num);
tail = tail->next;
}
// 插入節點
void insert(size_t idx, int data){
// 旗標(插入點的前一個)
Node* node = this->node;
for(unsigned i = 0; i < idx; ++i) {
node = node->next;
}
Node* temp = node->next;
node->next = init(data);
node->next->next = temp;
}
// 刪除鏈結
void del(){
for(Node* temp=node; temp; temp=node) {
node = temp->next;
free(temp);
}
}
// 印出節點
void print(){
for(Node* n = node->next; n; n=n->next) {
printf("%d, ", n->data);
} printf("\n");
}
};
操作方法
// 新增鏈結
Node_class list;
// 新增節點
list.append(1);
list.append(2);
list.append(3);
// 插入節點
list.insert(1, 0);
// 查看節點
list.print();
// 刪除鏈結
// list.~Node_class();
再來回頭看那三點
- 每一個函式呼叫都需要引入 Node*由於方法與資料的群組結構,每一個物件都帶有各自的資料,而這個物件可以呼叫這些方法,用的就是內帶的資料,每個物件帶有不同的資料。
- 為了方便識別函式是對屬於誰的,名稱帶前缀名物件的名字取代了函式的前缀名,這個物件是誰建立的就傭有哪些方法,如果不是則無法使用,我們再也不需要為了同名而困擾了。
- 結束之後自己要記得 delete之所以將她註解掉是因為並沒有影響,每一個物件再生命週期結束的時候都會自動呼叫一次解構子,也就是帶有~符號的類別名稱方法。
沒有留言:
張貼留言