論C 如何實現多繼承

2021-06-24 11:10:35 字數 2758 閱讀 2551

近日看到了乙個貼子,就是在c#語言中,如何實現多繼承的問題。相信涉獵c#不多的人(像我這樣的菜鳥),一看就覺得很可笑,c#肯定是不能實現多繼承的啊。都知道在c++中因為實現多繼承會有很多的歧義問題,所以在c#中就把多繼承給取消了,而用介面來實現!但是想想,如果是初學者肯定不會不會問這樣的問題。肯定是個高手,然後就開始上網查資料!然後發現真的可以實現!

說起多繼承,首先大家可以想想這個問題:你知道在

c#中怎麼實現多繼承嗎?

主流的答案無非2種。

答案一:用介面啊,乙個類可以繼承自多個介面的。

答案二:

c#不支援多繼承,

c++才支援多繼承,多繼承會讓**變得很亂,因此微軟在設計

c#的時候放棄了多繼承。

能夠知道答案二的人顯然懂的更多,我也在很長一段時間內相信

c#不支援多繼承,直到

2023年5

月的乙個專案中,我偶然的發現自己的**就完全實現了真正意義的多繼承。

先說說什麼是真正意義的多繼承。真正的多繼承應該是像

c++那樣的,而不是說像在

c#裡面乙個類繼承了多個介面就叫多繼承。在

c#中,如果乙個類實現了多個介面,那麼要為每個介面寫實現,如果介面被多個類繼承,那麼就會有重複的**,這顯然是無法接受的。

然而c++

那樣的多繼承也確確實實給編碼帶來了很大的麻煩,我也相信微軟真的是因為意識到了多繼承的不合理之處才在

c#中擯棄了這個特性。而我在

c#中實現的多繼承,第一是真正的多繼承,第二**寫的很合理。

請看案例

假如你有乙個類叫老虎,還有乙個類叫蒼蠅。現在你想新創乙個超級老虎類,一種可以飛的老虎。在

c++中,你可以定義一種超級老虎類,讓其繼承自老虎和蒼蠅,這樣這種老虎就可以飛了。然而,問題出現了,這種超級老虎由於同時也繼承自蒼蠅,而蒼蠅下面有個方法叫吃,引數型別是屎。吃屎的這個方法顯然跟我們的超級老虎太不搭了。

雖然這個例子有些誇張,但是很多

c++程式設計師真的就是這樣在設計**。由於子類繼承了多個父類,而多個父類肯定有些成員跟這個子類不搭調,於是子類的呼叫者就很難受了。比如上面這個例子,當呼叫者拿到超級老虎的乙個例項時,發現超級老虎下面怎麼會有個吃屎的方法呢!!!真的是要笑死人了。

c++要這樣允許多繼承就必然會造成這個問題。

c#程式設計師就絕對不會寫出這樣滑稽的**。對於

c#程式設計師,肯定是要把這個飛的方法提成介面的,然後讓蒼蠅類和超級老虎類都繼承自這個介面。這樣,蒼蠅會飛,超級老虎也會飛。是不是完美解決這個問題?

問題看上去解決了,但是,假如我跟你說蒼蠅飛的方法跟超級老虎飛的方法需要一模一樣:首先張開雙翅,身體前傾,拍打雙翅,起飛,繼續拍打。我們肯定不能把同乙份**

copy

乙份吧,那是屬於入門級程式設計師幹的事,我們現在已經沒資格幹那事了。那怎麼辦呢?

簡單快速的做法是使用靜態方法,比如

flyhelper.fly(...)

。靜態方法解決了**重用的問題,但寫起來始終覺得**不對勁。我的超級老虎類和蒼蠅都明明繼承了飛了啊,

為什麼還要這樣呼叫一句靜態方法。如果以後哪天我想讓我的豬也能飛起來,那豈不是還要來呼叫這個靜態方法。

到底怎樣才能在

c#中實現像

c++那樣優雅的繼承呢?

答案揭曉

答案其實很簡單,那就是給

ifly

介面寫擴充套件方法。

首先請看這個空介面的定義,及其擴充套件方法(注意泛型限制):

namespace inte***ce

//擴充套件方法

public static class extendfly

}}

再看老虎和蒼蠅的實現:

namespace inte***ce

}}

namespace inte***ce

}}

再看超級老虎的實現:

namespace inte***ce

public void tigerfly()

}}

怎麼樣,你看明白了嗎?這個實現是不是很簡單呢?好處是不是大大的有呢?

當以後哪天老闆讓你實現乙個會飛的超級豬的話,你只需要讓你的超級豬繼承「i

飛」介面就行了。當哪天老闆又不想要這個超級豬飛的話,你也只需要將這個介面繼承刪掉而已。如果你正在開發乙個動物王國程式,你可以將飛的功能注入到任何一種動物身上。想想是不是都覺得很爽。

總結

最後,再讓我們回顧一下之前用

c++寫的超級老虎吃屎的**例子。這實際上不是

c++的錯,而是程式設計師用錯了多繼承。雖然在語法上

c++沒有限制程式設計師怎麼去寫多繼承,但是從上面的例子分析來看,我們很容得出這樣乙個結論:

當需要寫多繼承的時候,被繼承的父類只能是乙個功能,而不應是乙個完整的類。

如果按照這個思路,那麼今天的這個例子在

c++中就可以這樣寫,首先提乙個

flyable

的類出來,然後讓超級老虎和蒼蠅都繼承這個

flyable。

在c#中,雖然實現多繼承的**稍微繞了個彎,但是多繼承帶來的好處是非常明顯的:對不同的類實現注入式的功能,讓你的**更符合物件導向的思想。

php 如何實現多繼承

記得有一道面試題問php是否支援多繼承?答案 不可以,只支援單繼承。如何實現多繼承呢?答案 可以使用 inte ce 或 trait 實現 為什麼會想到這個問題,因為想到如果類繼承多個介面,然後他們之間還有相同的屬性和方法會引用誰的方法或屬性,誰又會被覆蓋?總結 1.使用 inte ce 宣告類不能...

C 介面實現多繼承

前言 本博文主要講解c 介面實現多繼承,更多關於介面 繼承的知識,請檢視 c 介面 inte ce 精講 c 隱式介面與顯式介面 c 繼承細則,你真的知道嗎?介面是方法的抽象,如果不同的類有同樣的方法,那麼就應該考慮使用介面。c 中介面可以多繼承,介面之間可以相互繼承和多繼承。乙個類可以同時繼承乙個...

C 多繼承 虛繼承

一,多繼承 include include using namespace std class b1 繼承類c void main 主函式 c類按照順序繼承b2,b1,b4,b3 再按照資料成員定義順序 memberb1,memberb4,memberb3,memberb2 最後是自己的構造器 二,...