Single inheritance and multiple inheritance exam questions

單一繼承與多重繼承考題

物件導向的繼承方式主要分為單一繼承與多重繼承兩種,C++與 JAVA 各屬何種繼承方法?又此二種繼承方法優缺點各為何?(10 分)針對單一繼承的缺點,可用介面

(Interface)來解決,請問介面如何解決?請舉例說明。(10 分

答案

(一)C++ 支援多重繼承,而 Java 則支援單一繼承。

(二)

**多重繼承**(Multiple Inheritance)的優點:

- 允許一個類別同時繼承多個父類別,可以繼承不同父類別的屬性和行為。

- 提供了更大的彈性,可以更容易地重用程式碼。


**多重繼承**的缺點:

- 引入複雜性:多重繼承可能導致衝突和不清晰的程式碼,特別是當多個父類別具有相同名稱的屬性或方法時。

- 隨著繼承關係的增加,繼承鍊可能變得複雜,難以理解。

- C++ 使用多重繼承時,必須小心處理「鑽石繼承」(Diamond Inheritance)問題,這可能導致二義性(Ambiguity)。


**單一繼承**(Single Inheritance)的優點:

- 簡化了繼承體系,減少了可能的衝突和二義性。

- 提供了清晰的繼承鍊,更容易理解程式碼。


**單一繼承**的缺點:

- 限制了類別的重用,因為每個類別只能繼承一個父類別。

- 在某些情況下,可能需要重複編寫某些程式碼,以達到所需的功能。

(三)

**介面**在單一繼承中的作用是提供一種方式來實現類別之間的共享行為,同時解決了多重繼承可能帶來的問題。在 Java 中,一個類別可以實現多個介面,這種方式稱為多重實作(Multiple Implementation)。


舉例來說,假設有一個形狀(Shape)類別和一個可縮放(Scalable)介面,介面可以用來定義縮放行為。然後,不同類別(例如圓形和矩形)可以實現 Scalable 介面,以定義它們各自的縮放行為。


```java

public interface Scalable {

void scale(double factor);

}


public class Circle implements Scalable {

// 實現 Scalable 介面的縮放方法

@Override

public void scale(double factor) {

// 實作縮放邏輯

}

}


public class Rectangle implements Scalable {

// 實現 Scalable 介面的縮放方法

@Override

public void scale(double factor) {

// 實作縮放邏輯

}

}

```


這樣,我們可以在不引入多重繼承的情況下,實現不同類別的共享行為,同時避免了多重繼承可能帶來的問題。

補充

### 繼承鏈(Inheritance Hierarchy): 繼承鏈是指在一個軟體系統中,類別之間的繼承關係形成的一種層次結構。它表示類別的衍生和基底的層次結構,通常以樹狀結構表示。在這種結構中,一個類別可以繼承自另一個類別,形成父子關係,而這種關係可以一直延續形成一個鏈條,形成繼承鏈。 例如,如果有 `Animal` 類別,`Mammal` 和 `Bird` 類別分別繼承自 `Animal`,而 `Dog` 和 `Cat` 類別又分別繼承自 `Mammal`,那麼就形成了一個繼承鏈:`Animal` -> `Mammal` -> `Dog`/`Cat`。


### 鑽石繼承(Diamond Inheritance): 鑽石繼承是指在繼承鏈中,某個類別有兩個直接的基底類別,而這兩個基底類別又共同繼承自同一個類別,形成一個鑽石形狀的繼承結構。這種情況可能引發一些問題,特別是當派生類別需要使用從兩個基底類別中繼承的成員時。 例如,假設有 `A` 類別,`B` 和 `C` 類別分別繼承自 `A`,而 `D` 類別同時繼承自 `B` 和 `C`,形成了鑽石繼承的情況:`A` -> `B`、`A` -> `C`,最終 `B` 和 `C` 兩者的成員都在 `D` 中可見。 ```plaintext A / \ B C \ / D ``` 鑽石繼承可能導致一些問題,例如二義性(Ambiguity),即編譯器不知道使用哪個基底類別中的成員。為了解決這個問題,C++ 使用虛擬繼承(virtual inheritance)來標記這樣的基底類別,以避免產生多個實例造成的問題。

**二義性(Ambiguity)**:


使用多重繼承時,可能會出現二義性的情況,這表示一個類別有多個途徑繼承相同的成員。當你試圖訪問這個成員時,編譯器無法確定使用哪一條途徑,因此產生了二義性。這通常發生在鑽石繼承(Diamond Inheritance)結構中,其中一個類別有兩個以上的基底類別。


**虛擬繼承(Virtual Inheritance)**:


虛擬繼承是 C++ 中用來解決鑽石繼承二義性的概念。當某個類別需要從多個共同的基底類別中繼承時,可以使用虛擬繼承來標記這些基底類別。這樣一來,這些基底類別在繼承鏈中只會存在一個實例,而不是多個實例,從而避免了二義性。


```cpp

class A {

public:

void display() {

std::cout << "Class A" << std::endl;

}

};


class B : public virtual A {

};


class C : public virtual A {

};


class D : public B, public C {

};


int main() {

D obj;

obj.display(); // 沒有二義性,會正確呼叫 A 的 display

return 0;

}

```


在這個例子中,`B` 和 `C` 虛擬繼承自 `A`,而 `D` 類別繼承自 `B` 和 `C`。這樣,`D` 中只有一個 `A` 的實例,解決了二義性的問題。使用虛擬繼承時,應謹慎設計,以確保合理使用這種機制。

Comments

Popular posts from this blog

How to write data into a excel file using vbscript

Format date as yyyy-mm-dd using vbscript