设计接单子网站,wordpress视频解析插件,响应式网页设计原理,Wordpress 搜索自动补全关于接口#xff0c;每天的编码都在写#xff0c;就不多说了。这里对比下接口#xff0c;抽象类#xff0c;类3者的关系#xff1a; 1#xff09;#xff0c;接口是一种规范#xff0c;就是告诉外界这个东东可以做什么。 2#xff09;#xff0c;抽象类是一种模板每天的编码都在写就不多说了。这里对比下接口抽象类类3者的关系 1接口是一种规范就是告诉外界这个东东可以做什么。 2抽象类是一种模板就是告诉外界这个东西的一部分公共功能。 3类和上面的接口抽象类最大的区别就是类可以维护状态信息。 在以前的接口中 1没有构造方法,不能实例化 2接口只能继承接口,不能继承类 3接口里没有普通方法,方法全是抽象的 4接口里的方法默认修饰符是public abstract 5接口里的字段全是全局常量,默认修饰符是public static final java8中的接口在原来的基础上增加了一些功能主要是2个默认方法静态方法。1默认方法 首先来了解下为什么会出现默认方法这个东西。许多开发语言都将函数表达式集成到了其集合库中这样子比循环方式所需的代码更少并且更加容易理解。比如以前我们写循环代码for(int i 0; ilist.size();i)
{System.out.println(list.get(i));
} 现在我们使用函数函数式编程代码如下public static void main(String[] args){ListInteger list Lists.newArrayList(1, 2, 3);StreamInteger stream list.stream();stream.forEach(System.out::println);}现在假设我们自己不用流我们想直接在list集合上面提供一个forEach方法用来将一个函数应用到集合的每一个元素上面。下面是使用这种方式编写的代码list.forEach(System.out::println)上面的效果很好如果我们自己定义也就是说重新设计集合当然是没有问题的但是java的集合是许多年前设计的这就会带来一个问题我们为List接口增加了一个方法那么所有的实现类都要改过这样子代码才不会报错这基本是无法想象的。所以呢java设计者希望通过允许接口包含具体实现的方法来一劳永逸的解决这个问题。当然为接口提供默认方法还有别的好处我们一会会整理到。 java8中允许在接口中定义默认方法默认方法必须使用default来修饰。先来看一个例子熟悉下java8中默认方法的语法public class Test implements TestInterface
{public static void main(String[] args){Test test new Test();//使用自己类中的方法System.out.println(test.getId());//使用接口中的默认方法System.out.println(test.getName());}Overridepublic Integer getId(){return 25;}}interface TestInterface
{Integer getId();default String getName(){return 默认方法里面的输出。。。;}
} 上面的代码使用了TestInterface接口中定义的默认方法getName()程序执行没一点问题。当然我们也可以自己来重写接口中默认方法中的默认方法。public class Test implements TestInterface
{public static void main(String[] args){Test test new Test();//使用自己类中的方法System.out.println(test.getId());//使用接口中的默认方法System.out.println(test.getName());}Overridepublic Integer getId(){return 25;}Overridepublic String getName(){//默认使用接口中的默认方法注意下面的使用父类接口中方法的语法//return TestInterface.super.getName();return 自己的类中重写了接口中的默认方法;}}interface TestInterface
{Integer getId();default String getName(){return 默认方法里面的输出。。。;}
}在上面的使用过程中我们发现了现在使用java8接口的默认方法很好的解决了前面我说的问题了我们不必在每个实现类中都去实现接口中新加的方法了只需要在接口中增加一个default修饰的默认方法就好了。 另外在上面的编码过程中我们不难还能发现一个使用默认方法带来的好处我们现在可以很方便的在接口中指定本质上可选的方法根据接口的使用方式来选择使用的方法。举个例子吧比如我们定义了一个接口里面有一个删除元素的方法remove()但是实际情况是这个接口应该支持可修改和不可修改2种系列在可修改系列中没有问题我们直接实现remove()方法就好了不可修改系列我们不需要这个方法但是也只能定义一个remove()的空实现最好抛出一个异常。现在我们使用java8中的默认方法就避免了用于不可修改系列的类也必须定义自己的占位符性质的多余的方法总结一下就是说默认方法让一些类要去实现的方法变成了可选方法。总结一下 默认方法提供了2个优点 1优雅的随时间演化接口。也就是代码的向后兼容性 2提供可选功能类不必在不需要该功能的时候提供占位符实现。2多级继承的问题 java中的继承是单继承这个不多说了。现在考虑到接口新增的默认方法现在java是不是绕开了单继承呢明显不是。接口不能维护状态信息但是现在默认方法可以提供一些行为上面的多继承。比如说一个类实现2个接口在这2个接口中定义了2个默认方法那么这个类同时拿到了2个方法编码确实多了很大的灵活性。但是也会有一个很明确也是必须要解决的问题就是冲突问题比如说A类实现了B接口C接口如果B和C接口都提供了一个叫test的默认方法那A类将实现那个接口里面的test方法呢又比如说A类提供了自己的实现这时候将发生什么又比如说A同时也继承了一个有test方法的类那么这个时候有事什么情况呢 不慌的解决上面的问题很简单就是定义一组规则就好了按照一个约定来定义解决上面的冲突。具体的规则如下 1在所有的情况类实现的优先级高于接口的默认实现也就是先使用自己类中定义的方法或者是父类中的方法。类优先是解决上面系列问题的最主要的规则。 2当类同时实现了2个接口2个接口中如果包含相同的默认方法那么这个类中就必须重写这个接口不然代码报错。 3如果是一个接口继承了另外一个接口2个接口中也包含相同的默认方法那么继承接口的版本具有更高的优先级。比如A扩展了B接口那么优先使用A类里面的test方法。 4通过使用super可以显式的引用被继承接口的默认实现语法如下InterfaceName.super.methodName()。 相关代码如下public class Test extends C
{public static void main(String[] args){Test test new Test();System.out.println(test.getName());}}class C implements A, B
{Overridepublic Integer getId(){// TODO Auto-generated method stubreturn null;}//不管接口A和接口B中的这个方法是不是默认方法有没有提供实现都必须重写 不然代码报错Overridepublic String getName(){System.out.println(A.super.getName());return 自己类中必须重写这个方法。。。;}}interface A
{Integer getId();default String getName(){return 接口A。。。;}
}interface B
{default String getName(){return 接口B。。。;}}3在接口中使用静态方法 在java8中为接口新增了一项功能定义一个或者更多个静态方法。类似于类中的静态方法接口定义的静态方法可以独立于任何对象调用。所以在调用静态方法时不需要实现接口也不需要接口的实例也就是说哦和调用类的静态方法的方式类似。语法如下 接口名字.静态方法名。public class Test implements A
{public static void main(String[] args){System.out.println(A.getName());}}interface A
{static String getName(){return 接口A。。。;}
} 注意实现接口的类或者子接口不会继承接口中的静态方法。static不能和default同时使用。在java8中很多接口中都增加了静态方法比如下面代码public class Test
{public static void test(ListString list){//直接使用Comparator的静态方法list.sort(Comparator.comparing(String::length));}public static void main(String[] args){ListString list Lists.newArrayList(122,2,32);test(list);for (String str : list){System.out.println(str);}}}转载于:https://www.cnblogs.com/LinkinPark/p/5232972.html