接口
接口特性
- 接口不是類,不能使用new實例化一個接口;
- 不能構造接口的對象,但可聲明接口的變量;
- 接口變量必須引用實現了接口的類對象;
- 可以使用 instanceof 檢查一個對象是否實現了某個特定的接口;
- 可以建立類的繼承關係一樣,接口可以繼承接口進行擴展;
- 接口中不能包含實例域或靜態方法,但可包含常量;
- 接口中聲明的方法自動地設置爲public;
- 接口中的域(即常量)自動地設置爲 public static final;
Java8接口-新特性
- 靜態方法。
JavaSE8 允許在接口中增加靜態方法; - 默認方法。
可以爲接口方法提供一個默認實現,必須使用default修飾符標記這個方法; - 解決默認方法衝突問題:
如果接口中將一個方法定義爲默認方法,然後在超類或另一個接口中定義了同樣的方法。就要解決衝突,規則如下:
① 超類優先。如果超類提供了一個具體方法,同名且有相同參數類型的默認方法會被忽略。
②接口衝突。如果一個超接口提供了一個默認方法,另一個接口提供了一個同名而且參數類型相同的方法,必須覆蓋這個方法來解決衝突。
③類優先原則。如果一個類擴展了一個超類,同時實現了一個接口,並且從超類和接口繼承了相同的方法。此種情況使用類優先原則,接口的默認方法會被忽略。
接口測試具體用例
接口PersonInfo
/**
* @author gao tianci
* @version $Id: PersonInfo.java, v 0.1 2017年6月9日 下午5:19:14 gao tianci Exp $
*/
public interface PersonInfo {
//方法都自動設置爲public
void printAge();
//常量自動設置爲 public static final
String DEFAULT_NAME = "TIANCI";
int DEFAULT_AGE = 18;
String DEFAULT_SEX = "男";
//javaSE8可以有靜態方法
static void printSex() {
System.out.println(DEFAULT_SEX);
};
//javaSE8 可以爲接口方法提供默認實現,default進行標記
default void printName() {
System.out.println(DEFAULT_NAME);
};
}
接口PersonHobby
/**
* @author gao tianci
* @version $Id: PersonHobby.java, v 0.1 2017年6月9日 下午5:41:59 gao tianci Exp $
*/
public interface PersonHobby {
String DEFAULT_HOBBY = "運動";
default void printName() {
System.out.println("hobby name is:" + DEFAULT_HOBBY);
}
}
類Person
/**
* Person類實現了兩個接口,兩個接口中都有默認的實現方法printName()
* 造成衝突,解決衝突的辦法就是在類中覆蓋這個方法
* 方法具體實現可以是重寫,也可以選擇調用具體接口的默認實現方法
* @author gao tianci
* @version $Id: Person.java, v 0.1 2017年6月9日 下午5:19:00 gao tianci Exp $
*/
public class Person implements PersonInfo, PersonHobby {
private String age;
private String name;
{
age = "age init from Person.";
name = "name init form Person.";
}
@Override
public void printAge() {
System.out.println(age);
}
//兩個接口都有該方法默認實現,進行覆寫來解決衝突
//方法具體實現可以是重寫,也可以選擇調用具體接口的默認實現方法
public void printName() {
/*調用具體的接口默認實現
PersonInfo.super.printName();*/
/* 調用具體的接口默認實現
PersonHobby.super.printName();*/
System.out.println(name);
}
}
測試代碼
/**
* @author gao tianci
* @version $Id: Test.java, v 0.1 2017年6月9日 下午5:45:44 gao tianci Exp $
*/
public class Test {
public static void main(String[] args) {
Person person1 = new Person();
//可以使用接口聲明變量,變量必須引用實現了接口的類對象
//但對象的能力只擁有聲明的接口類型中的能力
//如person3和person4沒有printAge()的能力
PersonInfo person2 = new Person();
PersonHobby person3 = new Person();
PersonHobby person4 = person1;
person1.printName();
person1.printAge();
System.out.println("-------");
person2.printName();
person2.printAge();
System.out.println("-------");
person3.printName();
person4.printName();
/*
* 對象的能力只擁有聲明的接口類型中的能力
* person3和person4沒有printAge()能力,下面方法不可用
* person3.printAge();
* person4.printAge();
*/
//使用接口調用接口中聲明的靜態方法
System.out.println("----接口中靜態方法---");
PersonInfo.printSex();
System.out.println("----訪問接口中常量---");
System.out.println(PersonInfo.DEFAULT_AGE);
System.out.println(PersonInfo.DEFAULT_NAME);
System.out.println(PersonInfo.DEFAULT_SEX);
System.out.println(PersonHobby.DEFAULT_HOBBY);
}
}
測試結果:
name init form Person.
age init from Person.
-------
name init form Person.
age init from Person.
-------
name init form Person.
name init form Person.
----接口中靜態方法---
男
----訪問接口中常量---
18
TIANCI
男
運動