答案是:可以,但必须是public static final的。
既然JDK1.7开始支持接口中存在default方法和static方法,那么这些方法在实现上,难免需要一些变量提供数据支持。
先看一个例子:
//基于JDK1.8
//IA.java
public interface IA {
int a = 100;
double NUM = 1;//等价于public static final double NUM = 1;
String name = "IA";
void say();
default void print() {
System.out.println("IA:print()");
}
default void pritA() {
System.out.println("IA: " + name);
}
}
//IB.java
public interface IB {
int b = 200;
double NUM = 2;
String name = "IB";
void say();
default void print() {
System.out.println("IB:print()");
}
default void pritB() {
System.out.println("IB: " + name);
}
}
//AB.java
public class AB implements IA, IB {
public static void main(String[] args) {
AB ab = new AB();
//ab.name 报错,不能确定是IA中的name还是IB中的
System.out.println(a);//100 因为a和b本质上是静态成员,在静态方法里面可以直接访问
System.out.println(b);//200
System.out.println(IA.NUM);//1.0
System.out.println(IB.NUM);//2.0
System.out.println(IA.name);//IA
System.out.println(IB.name);//IB
ab.say();//AB:say()
ab.print();//AB:print()
ab.pritA();//IA: IA
ab.pritB();//IB: IB
}
//必须实现接口中未实现的方法,并且根据排序规则,实现的是IA中的say()
@Override
public void say() {
System.out.println("AB:say()");
}
//必须重写IA和IB中重复(签名相同)的default方法,否则调用print时不知道调用IA中的实现,还是IB中的。
@Override
public void print() {
System.out.println("AB:print()");
}
}
据此得出结论:
- 接口中的成员变量默认且只能是public static final的,加这几个访问修饰符是多余的。
- 接口中的成员变量在实现类中可以直接访问(不管是静态方法还是非静态方法),如果父接口中有重复出现的成员变量,则只能带上接口名加以区分。
- 接口中default修饰的方法,为子类提供默认实现。
- 子类实现多个接口,多个接口中有同样签名的方法时,根据排序规则,以写在前面的接口为准。如果父接口中的default方法有重复,则子类必须重写此方法(不然,多个接口中分别提供了各自的实现,子类会不知道调用哪一个)。