【Java】淺析Java爲何拋棄了C++的多繼承

當初學C++繼承的時候,一開始確實被裏面亂七八糟的關係弄的暈得不輕。單繼承、多繼承、虛繼承.....Ծ‸Ծ

當時好像聽過一句話:“等你學Java的時候就好了,Java把這些東西都扔了” 罒ω罒//偷笑.jpg

爲什麼會丟棄這些東西嘞?往下看:

#include<iostream>   //錯誤代碼
using namespace std;
class A{
	
	public:
		int a=1;
    void ex(){
        cout<<"This is A"<<endl;
    }
}; 
class B:public A{
	public:
	    void f(){
	        cout<<"This is B"<<endl;
	    }
};
class C:public A{
	public:
    void f(){
        cout<<"This is C"<<endl;
    }
};
class D:public B,public C{
    void ee(){
        cout<<"this is D"<<endl;
    }
};
int main(){
    D d;
    cout<<d.a<<endl;
//    d.B::f();
    cin.get();
    return 0;
}

這是一個關於多重繼承的小例子,如圖:

這裏編譯時會顯示出錯:

 

出錯原因是因爲,系統不知道這個a,是D去繼承,B繼承A而來的還是C繼承A而來的(二義性)。因爲D通過繼承B、C帶來了兩個

A的副本。這裏可以通過改寫成:

int main(){
    D d;
    cout<<d.B::a<<endl;  //指定這是訪問d繼承B從A繼承來的a
    return 0;
}

來更正(很雞肋對吧)

當然,也可以用虛繼承去解決這個問題(讓D裏面只保留一個A的副本)(B、C繼承A時加上virtual,聲明這是虛繼承):

#include<iostream>
using namespace std;
class A{
	
	public:
		int a=1;
    void ex(){
        cout<<"This is A"<<endl;
    }
}; 
class B:virtual public A{
	public:
	    void f(){
	        cout<<"This is B"<<endl;
	    }
};
class C:virtual public A{
	public:
    void f(){
        cout<<"This is C"<<endl;
    }
};
class D:public B,public C{
    void ee(){
        cout<<"this is D"<<endl;
    }
};
int main(){
    D d;
    cout<<d.a<<endl;
//    d.B::f();
    cin.get();
    return 0;
}

以上就是多繼承中的菱形繼承問題,用virtual解決之後就完了?沒辣麼簡單。

如果B和C中都有一個函數f( ),直接寫d.f()還是會報錯,因爲機子又不知道這個f()哪來的了((~ ̄(OO) ̄)ブ)

還是二義性問題:

還是一樣,改寫main函數,可以更正過來:

int main(){
    D d;
    d.B::f();   //指定這是d調用B的f()
    return 0;
}

 總結:多繼承的實用性不強,並且多繼承中錯綜複雜的關係降低了程序的容錯率。

這也許就是Java將其拋棄之的原因吧(罒ω罒)

另一方面,Java也提出了Interface(接口)的概念,藉以彌補多繼承的功能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章