深入理解java中的接口 (Interface)

概念

我們知道java中是單繼承的,這就有了很多的限制,比如我們需要多繼承的時候但是不能用多繼承,這時候怎麼辦呢?就引入了接口的概念,它彌補了java中單繼承的缺陷,這一點非常的好,如果要約定子類的實現要求並避免單繼承侷限就需要使用接口。

那麼什麼是接口呢?

接口就是抽象方法和全局常量的集合,使用Interface關鍵字。

定義

接口如何定義?它與類又有什麼區別呢?
我們先來定義一個接口
例如:

Interface IMessage{
	public static final String COUNTRY="China";//全局常量
	public abstract void print();//抽象方法
}

上面這樣的代碼就是一個簡單的接口的定義,我們爲了區分接口,一般在接口名稱前加上字母Interface的首字母I並且大寫。

由於接口中的方法都是抽象方法和全局常量,我們一般可以省略抽象方法前面的修飾public abstract,以及常量前面public static final的修飾,例如:

Interface IMessage{
	String COUNTRY="China";//全局常量
	void print();//抽象方法
}

我們會發現接口裏面並沒有一些具體的信息,那麼我們如何使用接口呢?

接口和抽象類一樣,不能直接實例化,抽象類由繼承它的子類實現它的抽象方法,那麼接口也有自己的實現類,可以通過接口的實現類實現實例化。

對於它的實現類:

接口的實現類必須實現接口中的所有抽象方法,然後實現類可以通過向上轉型爲它的任意接口,然後實例化。

例如下面的代碼:

interface IMessage{
    public static final String MSG = "message" ; // 全局常量
    public abstract void print() ; // 抽象方法
}
interface INews {
    public abstract String getNews() ;
}
class MessageImpl implements IMessage,INews {
    public void print() {
        System.out.println(IMessage.MSG) ;
    }
    public String getNews(){
        return IMessage.MSG ; // 訪問常量都建議加上類名稱
    }
}
public class Test{
    public static void main(String[] args) {
        IMessage m = new MessageImpl() ; //子類向上轉型,爲父接口實例化對象
        m.print() ; // 調用被子類覆寫過的方法
        INews n = (INews) m ;
        System.out.println(n.getNews()) ;
    }
}

我們看看上面這段代碼的轉換關係如下:
在這裏插入圖片描述

接口的使用限制

在上面的定義中我們知道了接口中,不論是屬性還是方法,權限都是public的,那麼這就決定了子類在實現接口時實現接口抽象方法的權限只能是public。

有些人實現的時候習慣和接口中一樣權限什麼都不寫,這樣是錯誤的,因爲什麼都不寫默認的權限是default權限的,它的權限低於public,就會容易出錯。

當一個子類既需要繼承父類又需要實現接口時,應該先繼承再實現

例如:

interface IMessage {
    public void print() ;
}
abstract class News {
    // 抽象類中方法前面的abstract不能省略,否則就是普通方法
    public abstract void getNews() ;
}
class MessageImpl extends News implements IMessage {
    public void print() {
        System.out.println("I am a biter") ;
    }
    public void getNews() {
        System.out.println("I am News") ;
    }
}

需要注意的是:一個抽象類可以實現多個接口,但是接口不能繼承類,接口可以繼承接口

看一個抽象類實現接口的例子:

interface IMessage {
    public void print() ;
}
abstract class News implements IMessage{
    //News爲抽象類,可以不實現IMessage中的抽象方法
// 抽象類中方法前面的abstract不能省略,否則就是普通方法
    public abstract void getNews() ;
}
class MessageImpl extends News {
    public void print() {
        System.out.println("I am a biter") ;
    }
    public void getNews() {
        System.out.println("I am News") ;
    }
}

當然,在java中,一個接口可以繼承多個父接口,例如:

interface A {
    public void printA() ;
}
interface B {
    public void printB() ;
}
interface C extends A,B { // 接口多繼承
    public void printC() ;
}
class Impl implements C{
    public void printA() {}
    public void printB() {}
    public void printC() {}
}
public class Test{
    public static void main(String[] args) {
    }
}

總結

  • 接口裏定義抽象方法
  • 接口裏定義常量
  • JDK7-11接口的一些變量(默認方法)
  • 接口是無法實例化的,只能通過實現類
  • 接口實現類可以向上轉型成它實現的任意一個接口類型
  • 在接口中定義的變量實際是常量,並且public static final 修飾的
  • 接口中定義的方法是一個抽象方法,默認使用public abstract 修飾的
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章