Java中類繼承、介面實現的一些細節(長期更新)

五月的倉頡發表於2015-10-21

前言

在Java中,子類繼承父類,類實現介面是屬於常識性的內容了,作為一個Java程式設計師應該也比較熟悉。不過子類繼承父類,類實現介面中還是有一些小細節值得注意一下,本文就從個人工作、學習中入手,總結一些細節性的內容,以更進一步地掌握繼承、實現的關係。現在只是寫一些目前碰到的內容,以後只要想到了、碰到了任何繼承、實現相關問題,都會保持更新此文。

 

介面A有void C()方法,介面B有int C()方法,則無法同時實現這兩個介面

Java為了彌補類單繼承的不足,引入了類多實現介面的機制,不過多實現某個介面也是有一定限制的,比如:

public interface A
{
    void C();
}
public interface B
{
    int C();
}

那麼同時實現這兩個介面是不可能的:

這個錯誤是無法被修復的。試想,類AB實現介面A和介面B,那麼介面A裡面的抽象方法和介面B裡面的抽象方法引數列表都相同僅有返回值不同,類AB應該實現哪個呢?實現介面A的"void C()",那麼介面B的"int C()"怎麼辦?實現介面B的"int C()"那麼介面A的"void C()"怎麼辦?因為"void C()"、"int C()"屬於方法引數相同,返回值不同,這兩個方法是不可以過載的,所以同時實現兩個方法也不可能。因此,在這裡Java只能報錯了。

 

A是介面,B實現A,C繼承B,則C也是A的子類

有一個介面A,B實現了A介面,C繼承自B類,則C也是A的子類,看一下:

public interface A
{

}
public class B implements A
{

}
public class C extends B
{

}
public static void main(String[] args)
{
    C c = new C();
    System.out.println(c instanceof A);
}

返回結果是true。這是一個不難理解的結論,想到求證這個結論是因為有一次在研究LinkedHashMap的時候:

public class LinkedHashMap<K,V>
    extends HashMap<K,V>
    implements Map<K,V>

既然LinkedHashMap已經繼承了HashMap了,HashMap是Map的實現類,那為什麼LinkedHashMap還要實現Map呢,豈不是多此一舉嗎?由此想到了會不會是因為繼承了HashMap不代表LinkedHashMap是Map的子類所以LinkedHashMap要專門再實現一下Map,做了上面的實驗,發現是我多慮了,可能Sun的開發人員就想這麼寫吧,呵呵。

 

父子類中有同名屬性

這不是錯誤,只是會造成歧義而已,而且也可能會造成返回我們不想要的結果,主要原因可能是開發者對父類程式碼不熟悉所導致的(尤其是在父類定義的屬性一大堆的場景下)。舉個例子:

public class Father
{
    private int i;
    
    public Father()
    {
        
    }
    
    public Father(int i)
    {
        this.i = i;
    }
    
    public int getFatherI()
    {
        return i;
    }
}    
public class Son extends Father
{
    private int i;
    
    public Son(int i)
    {
        super(100);
        this.i = i;
    }
    
    public int getSonI()
    {
        return i;
    }
}
public static void main(String[] args)
{
    Son son = new Son(50);
    System.out.println("Son getFatherI():" + son.getFatherI());
    System.out.println("Son getSonI():" + son.getSonI());
}

執行結果為:

Son getFatherI():100
Son getSonI():50

提出這個問題是因為我們擔心父子類的同名屬性會不會存在覆蓋的情況,從執行結果來看,完全不用擔心這個問題。

 

一個實現類繼承自一個抽象類並且實現了多個介面,那麼必須實現所有未被實現的抽象方法

舉個例子:

public interface InterfaceA
{
    void A1();
    void A2();
}
public interface InterfaceB
{
    void B1();
    void B2();
}
public abstract class AbstractC implements InterfaceA, InterfaceB
{
    public void A1(){} // 我實現了InterfaceA的A1()方法
    public void B2(){} // 我實現了InterfaceB的B2()方法
    
    abstract void C(); // 我自己定義了一個抽象方法
}

那麼要定義一個ClassD繼承自AbstractC,則必須:

public class ClassD extends AbstractC
{
    public void A2(){} // 我必須實現InterfaceA中未被實現的A2()方法

    public void B1(){} // 我必須實現InterfaceB中未被實現的B1()方法

    void C(){} // 我必須實現AbstractC中未被實現的C()方法
}

相關文章