Re: [問題] 面試時被問到介面功能
※ 引述《Killercat (殺人貓™)》之銘言:
: 為什麼物件導向語言大多數都會禁止多重繼承?以及為什麼C++不算真正的OO語言?
: 其實有一部分的原因(不是全部)都跟一個關鍵字有關:鑽石型繼承
: 簡單的說就是
: A
: B C
: D
: B繼承A C繼承A D繼承於B以及C,這種東西稱為鑽石繼承
: 乍看之下沒有什麼問題,但是我們舉個很簡單的例子來看,馬上就知道問題出在哪
: A = java的Object,B C都是java bean 所以當然理所當然的繼承了Object
: A有一個原生的實作叫做Object.toString() BC都overload了toString
: 那要是有多重繼承的話 D.toString會是什麼?
補充一下鑽石繼承。
鑽石繼承的問題不在於 Object.toString() 被 B/C 都 override
(我想你寫 overload 是筆誤?)而產生 ambiguity。這方面與有
兩個 superclass 而兩者有一樣 signature 的 method 的問題無異。
其實剛巧我在 C/C++ 版有答過相關的問題:#19kSHvJ- 。
Diamond inheritence 出的問題在於 D 裡有多於一份的 A
所謂 inheritence, 在大部份 language 裡其實都是以“包含 super
class 的 instance" 來達成。比如 B extends A,其實可以想像成
B 裡面有一份 A:
+---------+
| B |
| +-----+ |
| | A | |
| +-----| |
+ --------+
你提的例子,在沒有適當處理下,會變成:
+---------------------+
| D |
| +-------+ +-------+ |
| | B | | C | |
| | +---+ | | +---+ | |
| | | A | | | | A | | |
| | +---+ | | +---+ | |
| +-------+ +-------+ |
+---------------------+
這會有什麼問題?比如說:
class A{
int counter = 0;
int increment() { return ++counter; }
}
class B extends A {
void foo() { println("increment result " + increment()); }
}
class C extends A {
void bar() { println("increment result " + increment()); }
}
class D extends B, C { }
假如我有
D d;
d.foo();
d.bar();
出乎意料以外,foo() bar() 都會印出 1:雖然裡面都跑了 A::increment()。
問題出在上面提到的:其實 B & C 都自帶了獨立的 A,所以 B/C 跑 increment
的話,其實是在 increment 不同的 A
所謂 virtual inheritence 就是把 兩份 A 變為一份:
+---------------------+
| D |
| +-------+ +-------+ |
| | B | | C | |
| +-------+ +-------+ |
| ↘ ↙ |
| +---+ |
| | A | |
| +---+ |
+---------------------+
那麼不論我經 B 或 C 而acess 到的 A 都是同一份。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 223.19.45.228
→
10/18 08:35, , 1F
10/18 08:35, 1F
推
10/18 09:05, , 2F
10/18 09:05, 2F
推
10/18 10:30, , 3F
10/18 10:30, 3F
推
10/18 12:00, , 4F
10/18 12:00, 4F
→
10/18 12:02, , 5F
10/18 12:02, 5F
推
10/18 13:14, , 6F
10/18 13:14, 6F
推
10/18 14:36, , 7F
10/18 14:36, 7F
推
10/19 15:21, , 8F
10/19 15:21, 8F
推
10/25 00:40, , 9F
10/25 00:40, 9F
討論串 (同標題文章)
java 近期熱門文章
PTT數位生活區 即時熱門文章