Java介面-多重繼承-Java程式設計思想
概述
最近把Java基礎知識梳理了一下,發現了一些以前理解有偏差的地方,記錄在此。
疑問
- 一個類同時繼承基類和多個介面時,該類中是否可以不實現介面中的方法?
- 一個類同時實現多個介面,能否向上轉型到各介面?
- 一個類同時實現多個介面,介面中的方法簽名是否可以保持一樣?
程式碼解惑
package think.in.java.interfaces;//: interfaces/Adventure.java
// Multiple interfaces.
import static net.mindview.util.Print.print;
interface CanFight {
void fight();
}
interface CanSwim {
void swim();
}
interface CanFly {
void fly();
}
class ActionCharacter {
public void fight() {
print("base class fight method");
}
}
/**
* 繼承一個類、多個介面
*/
class Hero extends ActionCharacter
implements CanFight, CanSwim, CanFly {
public void swim() {
print("sub class swim method");
}
public void fly() {
print("sub class fly method");
}
// @Override
// public void fight() {
// print("sub class fight method");
// }
}
public class Adventure {
public static void t(CanFight x) {
// 如果 Hero 沒有重寫父類的fight方法,則呼叫父類的fight方法
x.fight();
}
public static void u(CanSwim x) {
x.swim();
}
public static void v(CanFly x) {
x.fly();
}
public static void w(ActionCharacter x) {
// Hero 沒有重寫父類的fight方法,則呼叫父類的fight方法
x.fight();
}
public static void main(String[] args) {
Hero h = new Hero();
t(h); // Treat it as a CanFight
u(h); // Treat it as a CanSwim
v(h); // Treat it as a CanFly
w(h); // Treat it as an ActionCharacter
}
} ///:~
輸出:
base class fight method
sub class swim method
sub class fly method
base class fight method
一個類同時繼承基類和多個介面時,該類中是否可以不實現介面中的方法?
我們發現,Hero
實現了CanFight
介面,CanFight
介面中定義了fight()
方法。但是在Hero
中卻並沒有實現該方法。
其實這個問題也好理解,因為Hero
類繼承了ActionCharacter
基類,而ActionCharacter
基類中實現了fight()
方法。父類的方法,子類自然有許可權使用。
所以,在CanFight x
和ActionCharacter x
引用呼叫fight()
方法時,自然引用到了基類的fight()
方法。
一個類同時實現多個介面,能否向上轉型到各介面?
這個從程式碼中我們可以看到,Hero
子類可以作為引數傳遞給CanFight
、CanSwim
、CanFly
等型別。所以,是可以向上轉型到各介面的。
Java允許實現多個介面,而不是繼承多個類。這消除了我們在組合相同基類實現時使用的兩個相同成員的不確定性。
看程式碼:
/**
* 第一個介面
*/
interface BaseInterface {
void f();
}
interface IntermediateInterface1 extends BaseInterface {
void f();
}
interface IntermediateInterface2 extends BaseInterface {
void f();
}
/**
* 多重繼承介面
*/
interface CombinedInterface
extends IntermediateInterface1, IntermediateInterface2 {
void f();
}
class CombinedImpl implements CombinedInterface {
public void f() {
System.out.println("CombinedImpl.f()");
}
}
/**
* 建立一個介面,並從該介面繼承兩個介面,然後從後面兩個介面多重繼承第三個介面
*/
public class E13_Diamond {
public static void main(String[] args) {
new CombinedImpl().f();
}
} /* Output:
CombinedImpl.f()
*///:~
一個類同時實現多個介面,介面中的方法簽名是否可以保持一樣?
CombinedImpl
實現了CombinedInterface
,而CombinedInterface
又分別繼承了IntermediateInterface1
和IntermediateInterface2
介面,IntermediateInterface1
和IntermediateInterface2
介面繼承了BaseInterface
介面。
而這些介面都有’f()’方法。所以是可以的。
試想一下,如果同時繼承兩個基類,而碰巧兩個基類中有同樣的方法。那麼向上轉型後,呼叫該方法,程式是不是就不知道該呼叫A基類的方法還是B基類的方法了呢? 不過介面是可以這麼幹的。