对比jdk1.7抽象类与jdk1.8接口默认方法的设计差异
在jdk1.8之前,接口只能定义方法,共享的实现必须放在抽象类中。jdk1.8引入了使用default关键字在接口中定义默认方法的能力。这改变了抽象设计,使接口可以提供有默认行为的方法实现,类似于抽象类,但避免了单继承的限制。实现类可以直接调用默认方法,也可以选择重写。注意,这可能导致类似多重继承的菱形问题。
诊断题
在jdk1.8中,为什么要在接口中引入默认方法(default method)?它解决了接口设计中的什么问题,并可能带来什么新挑战?
答案骨架
我能解释:1) 在jdk1.8之前,接口方法必须全部是抽象的,共享的通用实现只能放在抽象类中,这限制了接口的演进;2) 使用default关键字定义的方法提供了默认实现,允许向现有接口添加新功能而不破坏已有的实现类;3) 这类似于抽象类,但允许一个类实现多个接口,避免了单继承的限制,但也引入了多重继承的冲突风险。
边界追问
如果一个类同时实现了两个接口,这两个接口有一个同名的默认方法,会发生什么?
边界答案
在这种情况下,编译器会报错,因为出现了二义性。解决方法是:1) 在实现类中必须重写该冲突的方法,明确指定使用哪一个,或者提供自己的实现;2) 可以使用InterfaceName.super.methodName()的语法来调用指定接口的默认实现。这体现了菱形继承问题的处理原则。
记忆锚点
接口终于能‘自带干粮’(默认实现),但‘多吃一家’(多实现)时,饭要自己端(重写解决冲突)。
落地场景
定义接口IFormula,包含抽象方法calculate(int a)和默认方法sqrt(int a)(返回Math.sqrt(a))。一个匿名内部类实现了calculate后,可以直接调用formula.sqrt(2)获得结果。