概念
我們知道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 修飾的