文章目录
1 接口特性
- 接口不是类,不能使用 new 实例化一个接口;
- 不能构造接口的对象,但可声明接口的变量;
- 接口变量必须引用实现了接口的类对象;
- 可以使用 instanceof 检查一个对象是否实现了某个特定的接口;
- 可以建立类的继承关系一样,接口可以继承接口进行扩展;
- 接口中不能包含实例域或静态方法,但可包含常量;
- 接口中声明的方法自动地设置为 public;
- 接口中的域(即常量)自动地设置为 public static final;
2 Java8接口-新特性
- 静态方法。
JavaSE8 允许在接口中增加静态方法; - 默认方法。
可以为接口方法提供一个默认实现,必须使用 default 修饰符标记这个方法; - 解决默认方法冲突问题:
如果接口中将一个方法定义为默认方法,然后在超类或另一个接口中定义了同样的方法。就要解决冲突,规则如下:
① 超类优先。如果超类提供了一个具体方法,同名且有相同参数类型的默认方法会被忽略。
②接口冲突。如果一个超接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型相同的方法,必须覆盖这个方法来解决冲突。
③类优先原则。如果一个类扩展了一个超类,同时实现了一个接口,并且从超类和接口继承了相同的方法。此种情况使用类优先原则,接口的默认方法会被忽略。
3 具体用例
接口PersonInfo
/**
* @version $Id: PersonInfo.java, v 0.1 2017年6月9日 下午5:19:14
*/
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
/**
* @version $Id: PersonHobby.java, v 0.1 2017年6月9日 下午5:41:59
*/
public interface PersonHobby {
String DEFAULT_HOBBY = "运动";
default void printName() {
System.out.println("hobby name is:" + DEFAULT_HOBBY);
}
}
类Person
/**
* Person类实现了两个接口,两个接口中都有默认的实现方法printName()
* 造成冲突,解决冲突的办法就是在类中覆盖这个方法
* 方法具体实现可以是重写,也可以选择调用具体接口的默认实现方法
* @version $Id: Person.java, v 0.1 2017年6月9日 下午5:19:00
*/
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);
}
}
测试代码
/**
* @version $Id: Test.java, v 0.1 2017年6月9日 下午5:45:44
*/
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
男
运动