Java8新特性-接口中的静态方法与默认方法
今天上午在读《Effective Java》时,有这样一句话:”接口中“不能有静态方法,于是联想起面试时老是被问接口相关的东西,决定总结一下,谁知道这一总结,就发现了自己知识的一大漏洞。
在以前的思维中,接口中所有的方法都是抽象的,而抽象的方法没有static,有static的方法不能被override。但是在java8以后,允许在接口里定义默认方法和类方法。
一、接口代码
TestInterfac:
[code] public interface TestInterface { //此处的静态方法只能被public修饰(或者省略不写),不能是private或者protected。 static void out1() { System.out.println("接口的静态输出方法1"); } void out2(); default void out3() { System.out.println("默认输出方法3"); } }
实现类 TestImpl:
[code]public class TestImpl implements TestInterface{ public static void main(String[] args) { TestInterface.out1(); TestImpl demo = new TestImpl(); demo.out2(); demo.out3(); } @Override public void out2() { System.out.println("实现普通输出方法2"); } }
运行结果:
当我们在实现接口时,发现默认只需要实现out2方法,因为只有out2方法是抽象的。当然也可以手工实现将out3()方法重写,但是不能够重写静态方法out1。可以用TestInterface.out1()直接调用接口中的静态方法。
当创建demo对象时,可以直接调用out2,out3,但不可以调用静态方法out1()。为什么不能调用out1()?因为一个类可以实现多个接口。如果2个接口具有相同的 static 方法,则它们都将被继承,编译器将不知道要调用哪个。
Java8为什么要引入默认方法?
默认方法的主要优势是提供一种拓展接口的方法,而不破坏现有代码。加入我们有一个已经投入使用接口需要拓展一个新的方法,在JDK8以前,如果为一个使用的接口增加一个新方法,则我们必须在所有实现类中添加该方法的实现,否则编译会出现异常。如果实现类数量少并且我们有权限修改,可能会工作量相对较少。如果实现类比较多或者我们没有权限修改实现类源代码,这样可能就比较麻烦。而默认方法则解决了这个问题,它提供了一个实现,当没有显示提供其他实现时就采用这个实现。这样新添加的方法将不会破坏现有代码。
默认方法的另一个优势是该方法是可选的,子类可以根据不同的需求Override默认实现。
二、继承的父类和实现的接口中有相同的方法
父类TestClass:
[code] public class TestClass { public void out3() { System.out.println("我是父类中的输出方法3"); } }
子类:
[code]public class TestImpl extends TestClass implements TestInterface{ public static void main(String[] args) { TestInterface.out1(); TestImpl demo = new TestImpl(); demo.out2(); demo.out3(); } @Override public void out2() { System.out.println("实现普通输出方法2"); } }
运行结果:
所以,当继承的父类和实现的接口中有相同签名的方法时,优先使用父类的方法。
三、实现的多个接口中有相同的方法。
接口1:
[code]public interface TestInterface { default void out3() { System.out.println("默认输出方法3"); } }
接口2:
[code]interface TestInterface2 { default void out3() { System.out.println("第二个接口中的默认输出方法3"); } }
实现类:
[code]public class TestImpl implements TestInterface,TestInterface2{ public static void main(String[] args) { TestImpl demo = new TestImpl(); demo.out3(); } }
当我们去写实现类的时候发现会报错,错因如下:
必须在实现类中通过重写方法解决冲突问题,否者无法通过编译,在重写的方法中可以通过 接口名.super.方法名(); 的方式显示调用需要的方法。
为什么java的接口里的属性必须是static的?并且要求必须是final的呢?
接口中的数据对所有实现类只有一份,所以是static
要使实现类为了向上转型成功,所以必须是final的(接口不能被实例化,所以接口里面如果是变量的话不会被赋初始值这样就会出问题,所以必须是final的。其实还是为了安全考虑的) 这样接口也能起到一定的模版的作用。
参考文章:https://blog.csdn.net/qq_34755766/article/details/82861916
https://www.cnblogs.com/wuyx/p/9129118.html
- Java8新特性Optional、接口中的默认方法与静态方法
- java8新特性之接口默认方法&静态方法
- Java8学习笔记 — 其它新特性【接口默认方法(静态方法)、重复注解、类型注解】
- Java 8 新特性:接口的静态方法和默认方法
- Java8新特性 接口默认方法,接口静态方法
- java8-新特性--(接口的默认方法与静态方法)
- Java8新特性Optional、接口中的默认方法与静态方法
- java8新特性——接口中的静态方法与默认方法
- java8新特性接口的默认方法和静态方法
- java8新特性——接口中的静态方法与默认方法
- Java8中新特性Optional、接口中默认方法和静态方法详解
- Java 8 新特性:接口的静态方法和默认方法
- Java8特性之接口的默认方法与静态方法
- Java8新特性之接口的默认方法和静态方法
- Java8新特性总结 - 1.接口新增默认方法和静态方法
- Java8 新特性之二---------接口的默认方法和静态方法
- Java8新特性之接口中的默认方法与静态方法
- Java8新特性之接口的默认方法和静态方法
- JDK8新特性:接口的静态方法和默认方法
- Java8之默认方法和静态接口方法