Java8新特性
总所周知Java8中对于接口增强,增加了接口的默认方法和静态方法,使得接口越来越趋近于抽象类,在这里对于接口和抽象类的区别就不再赘述,在这里仅仅只是对于Java类无法使用接口的默认方法的问题进行一个分析解释。
示例代码1
public class A extends B implements Hook{
public static void main(String[] args) {
A.say();
// A.hookSay();/*Static method may be invoked on containing interface class only*/
}
}
class B {
static void say(){
System.out.println("B");
}
}
interface Hook{
static void hookSay(){
System.out.println("Hook");
}
}
执行结果
B
在使用 A.hookSay() 时提示的错误是 Static method may be invoked on containing interface class only 说白了就是类不能继承接口的静态方法
为什么Java8已经允许接口定义静态方法,但仍不允许继承接口的类继承接口的静态方法呢?
网上有人解释说用接口大多数情况下对象的类型都是用接口类型声明的,如果是这样,重写静态方法就没用了。
但是如果以这个说法子类也不应该继承父类的静态方法,所以这个说法是说不通的。
示例代码2
网上还有另一个说法是一个类可以实现多个接口,如果2个接口具有相同的静态方法,它们都将被继承,编译器就不知道要调用哪个接口。
但是这样有一个问题,接口默认方法不也是会遇到相同的问题吗?
public class A implements Hook,Hook2{
@Override
public void say(){
System.out.println("A");
}
public static void main(String[] args) {
new A().say();
}
}
interface Hook{
default void say(){
System.out.println("Hook");
}
}
interface Hook2{
default void say(){
System.out.println("Hook2");
}
}
执行结果
A
如果一个类继承的2个接口具有相同的默认方法,编译器也不知道要调用哪个接口,于是Java就强制让这个继承2个接口的类必须重写那个重复的默认方法。
那为什么Java不允许静态方法也用这种方式去解决静态方法冲突的问题呢?
因为java中静态属性和静态方法可以被继承,但是没有被重写,而是被隐藏。
- 父类和子类拥有相同名字的属性或者静态方法时,父类的同名的属性或者方法形式上不见了,实际是还是存在的,这就是隐藏
- 所有属性和静态方法都可以被继承和隐藏而不能被重写
- 当发生隐藏的时候,声明类型是什么类,就调用对应类的属性或者方法,而不会发生动态绑定
结论
假如类可以继承接口的默认方法,如果2个接口都有具有相同的静态方法,而类则会在编译时候不知道该继承哪个接口的静态方法,并且也无法通过重写静态方法来避免冲突(静态方法不能被子类重写,只能被子类隐藏)
第一次写博客,有什么问题希望各位指出