Java8新特性之默认方法和静态方法
前言
在Java8之前,默认情况下,接口中的所有方法都是公共的和抽象的。但是这一限制在Java8中被打破了,Java8允许开发人员在接口中添加新方法,而无需在实现这些接口的类中进行任何更改。
为什么会有默认方法?
主要是为了方便扩展已有接口;如果没有默认方法,假如给Java中的某个接口添加一个新的抽象方法,那么所有实现了该接口的类都得修改,影响将非常大。
举个例子,Sortable
publicinterfaceSortable{ voidsort(); Tpeek(); }
sort()方法用于对象排序,Tpeek()用于获取指定元素,另外需要一个比较器类ObjectComparator来对对象进行排序。
publicclassObjectComparatorimplementsComparator{ @Override publicintcompare(Comparableo1,Comparableo2){ returno1.compareTo(o2); } }
SortableStringCollection是一个自定义集合类可以进行排序,并查看字符串指定元素,代码如下:
publicclassSortableStringCollectionimplementsSortable{ privateList items=newArrayList<>(); publicvoidadd(Stringitem){ items.add(item); } @Override publicvoidsort(){ items.sort(newObjectComparator()); } @Override publicStringpeek(){ returnitems.get(0); } }
同样,SortableNumberCollection是一个自定义集合类,其中包含可以使用接口方法进行排序和查看的数字列表指定元素,代码如下:
publicclassSortableNumberCollectionimplementsSortable{ privateList items=newArrayList<>(); publicvoidadd(Integeritem){ items.add(item); } @Override publicvoidsort(){ items.sort(newObjectComparator()); } @Override publicIntegerpeek(){ returnitems.get(0); } }
在Java8之前如果对接口Sortable
SortableNumberCollection都必须实现TsortAndPeek()方法。
Java8之后提供了一种新的实现方式,默认方法defaultmethod,我们可以对Sortable
publicinterfaceSortable{ voidsort(); Tpeek(); defaultTsortAndPeek(){//New'defaultmethod'addedintheinterface sort(); returnpeek(); } }
同时SortableStringCollection和SortableNumberCollection类不需要任何更改。这样可以减少我们对原有代码的改动。同时如果需要,还可以在实现此接口的任何类中重写该方法TsortAndPeek()的默认实现。
在下图中我们看到defaultMethod不通的标识:
在多继承中使用默认方法问题
如果两个或多个接口具有相同的默认方法签名,并且一个类实现了这两个接口,则将引发编译时错误。例如:
publicinterfaceInterface1{ voidmethodOne(Stringstr); defaultvoidnewMethod(){ System.out.println("Interface1:Newlyaddedmethod"); } } publicinterfaceInterface2{ voidmethodTwo(Stringstr); defaultvoidnewMethod(){ System.out.println("Interface2:Newlyaddedmethod"); } } publicclassInterfaceImplementationimplementsInterface1,Interface2{ @Override publicvoidmethodOne(Stringstr){ System.out.println("OverriddenmethodOne:"+str); } @Override publicvoidmethodTwo(Stringstr){ System.out.println("OverriddenmethodTwo:"+str); } }
此时代码会提示如下异常:
InterfaceImplementationinheritsunrelateddefaultsfornewMethod()fromtypesInterface1andInterface2
要解决此问题,我们将必须重写类InterfaceImplementation中的方法:
publicclassInterfaceImplementationimplementsInterface1,Interface2{ @Override publicvoidmethodOne(Stringstr){ System.out.println("OverriddenmethodOne:"+str); } //newMethodimplementedtoresolvetheconflict. @Override publicvoidnewMethod(){ System.out.println("InterfaceImplementation:Newlyaddedmethod"); } @Override publicvoidmethodTwo(Stringstr){ System.out.println("OverriddenmethodTwo:"+str); } }
我们总结一下:
- 类中的方法优先级最高。类或父类中声明的方法的优先级高于任何声明为默认方法的优先级。
- 如果无法依据第一条进行判断,那么子接口的优先级更高:函数签名相同时,优先选择拥有最具体实现的默认方法的接口,即如果B继承了A,那么B就比A更加具体。
- 最后,如果还是无法判断,继承了多个接口的类必须通过显式覆盖和调用期望的方法,显式地选择使用哪一个默认方法的实现。
在Java8中添加静态方法
接口定义的静态方法独立于任何对象调用。所以,在调用静态方法时,不需要实现接口,也不需要接口的实例,
就像“默认方法”一样,“静态方法”也可以添加到接口中。例如,我们可以添加一个静态方法DirectiongetDefaultDirection(),该方法将返回默认Direction,例如:
publicinterfaceSortable{ DirectiondefaultDirection=Direction.DESC; enumDirection{ ASC, DESC }; voidsort(); Tpeek(); staticDirectiongetDefaultDirection(){//'staticmethod'addedtotheinterface. returndefaultDirection; } }
在上面的示例中,可以使用类引用来调用静态DirectiongetDefaultDirection()方法:
Sortable.getDefaultDirection()
对默认方法和静态方法的一点思考
接口是设计模式中一种开闭原则的体验,而java8赋予了接口新的特性,使得接口使用起来更加的得心应手了,这也有助于我们更加内聚自己的代码结构了。Java源码中也有很多场景使用到了默认方法,例如:Iterator接口,我们在开发中可以多使用一些新的特性从而提高开发效率及增加代码的健壮性。
publicinterfaceIterable{ Iterator iterator(); defaultvoidforEach(Consumeraction){ Objects.requireNonNull(action); for(Tt:this){ action.accept(t); } } defaultSpliterator spliterator(){ returnSpliterators.spliteratorUnknownSize(iterator(),0); } }
总结
到此这篇关于Java8新特性之默认方法和静态方法的文章就介绍到这了,更多相关Java8默认方法和静态方法内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。