由于Java 8允许在名为Default Methods的接口中默认实现方法,因此在何时使用a之间似乎存在混淆abstract class.
那么什么时候应该使用与默认方法的接口,何时应该使用抽象类?抽象类在这种情况下仍然有用吗?
在Java 8中使用默认方法作为穷人的特征是一种安全的做法吗?
一些人声称如果你只是为了它而使用它们可能会让熊猫感到悲伤,因为它很酷,但这不是我的意图.还经常提醒的是,引入了默认方法来支持API演变和向后兼容性,这是事实,但这并不会使它们错误或扭曲以将它们用作特征本身.
我有以下实际用例:
public interface Loggable {
default Logger logger() {
return LoggerFactory.getLogger(this.getClass());
}
}
Run Code Online (Sandbox Code Playgroud)
或许,定义一个PeriodTrait:
public interface PeriodeTrait {
Date getStartDate();
Date getEndDate();
default isValid(Date atDate) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
无可否认,可以使用组合(甚至是辅助类),但它看起来更冗长,更混乱,并且不允许从多态性中受益.
那么,使用默认方法作为基本特征是否可行/安全,还是应该担心不可预见的副作用?
关于SO的几个问题与Java vs Scala特征有关; 这不是重点.我也不仅仅是在征求意见.相反,我正在寻找一个权威的答案或至少是现场洞察力:如果你在公司项目中使用默认方法作为特征,那么它是否真的是一个时间炸弹?
是否有为接口方法创建默认实现的首选方法或样式?假设我有一个常用的界面,在90%的情况下我想要的功能是相同的.
我的第一直觉是用静态方法创建一个具体的类.然后,当我想要默认功能时,我会将功能委托给静态方法.
这是一个简单的例子:
接口
public interface StuffDoer{
public abstract void doStuff();
}
Run Code Online (Sandbox Code Playgroud)
具体实施方法
public class ConcreteStuffDoer{
public static void doStuff(){
dosomestuff...
}
}
Run Code Online (Sandbox Code Playgroud)
使用默认功能的具体实现
public class MyClass implements StuffDoer{
public void doStuff(){
ConcreteSuffDoer.doStuff();
}
}
Run Code Online (Sandbox Code Playgroud)
这里有更好的方法吗?
编辑
在看到一些提议的解决方案后,我想我应该更清楚我的意图.本质上我试图解决Java不允许多重继承.另外要明确我不是要声明Java是否应该允许多重继承.我只是在寻找为实现接口的类创建默认方法实现的最佳方法.