多重继承的替代方案
在编写 Java 20 年左右之后,我第一次希望自己拥有多重继承权。但我没有,所以我正在寻找这个具体问题的替代方案。
真正的应用程序是某种ERP,有点复杂,所以我试图将这个问题转化为汽车。这只能到此为止,但这是我能做的最好的事情。
让我们从描述汽车可以做什么的界面开始:
public interface Car {
public String accelerate();
public String decelerate();
public String steerLeft();
public String steerRight();
}
现在我们有一个基本(但不是抽象)的实现:
public class BasicCar implements Car {
protected final String name;
public BasicCar( String name ) {
this.name = name;
}
// In the real word this method is important and does lots of stuff like calculations and caching
protected String doDrive( String how ) {
return name + " is " + how + "ing";
}
@Override
public String accelerate() {
return doDrive( "accelerat" );
}
@Override
public String decelerate() {
return doDrive( "decelerat" );
}
// This method is important, too
protected String doSteer( String where ) {
return name + " is steering to the " + where;
}
@Override
public String steerLeft() {
return doSteer( "left" );
}
@Override
public String steerRight() {
return doSteer( "right" );
}
}
在现实世界中,这本身就是DAO的门面。请注意,我需要这些方法并在那里,因为这是完成一些计算,翻译和缓存等实际工作的地方。doDrive
doSteer
以及一些更具体的实现:
public class Sportscar extends BasicCar {
public Sportscar( String name ) {
super( name );
}
// I need to call the super method
@Override
public String doDrive( String how ) {
return super.doDrive( how ) + " fastly";
}
}
public class Truck extends BasicCar {
public Truck( String name ) {
super( name, new BasicMotor(), new TruckySteerer() );
}
// I need to call the super method
@Override
public String doSteer( String where ) {
return super.doSteer( where ) + " carefully";
}
}
我现在能做的是:
Car mcqueen = new Sportscar( "McQueen" );
mcqueen.steerLeft() //-> "McQueen is steering left"
mcqueen.accelerate() // -> "McQueen is accelerating fastly"
Car mack = new Truck( "Mack" );
mack.steerLeft() //-> "Mack is steering left carefully"
mack.accelerate() // -> "Mack is accelerating"
我现在想做的是将这两者组合成一个共享其功能的:
Car red = new Firetruck( "Red" );
red.steerLeft() //-> "Red is steering left *carefully*"
red.accelerate() // -> "Red is accelerating *fastly*"
我尝试过/想到什么
我可以将两者的代码复制并粘贴到一个类中。但这绝不是一个好主意。在实际的应用程序中,这几乎是代码,所以这是一个更糟糕的想法。
我认为我在这里面临着一些重大的重写/重构。
所以我可以制作和装饰器,两者都可以使用。但这不起作用,因为和是从装饰对象内部调用的,而装饰器仅适用于来自“外部”的调用。因此,我也必须将这些方法放在装饰器中,这也不是一个好主意。Sportscar
Truck
Firetruck
doSteer
doDrive
因此,我可以使用Java8的新花哨功能,并制作和委托给这样的界面:doSteer
doDrive
@FunctionalInterface
interface Driver {
public String doDrive( String where );
}
然后把它喂给构造函数,但是(除了变得非常复杂和得到一些其他相当讨厌的java问题)我再也无法以一种好的方式访问状态了。BasicCar
final
BasicCar
所以现在我在这里有点迷茫。任何好的想法都会得到赞赏。
编辑:举个例子,这在现实世界中看起来如何:该组可能是这样的:doSteer
class ProductImpl {
String getTitle(){
return getField( "title" );
}
String getTeaser(){
return getField( "teaser" );
}
String getField( String name ){
Locale loc = configuredLocale();
Map vars = configuredVarialbes();
String value = getCached( name, loc );
value = translateVariables( value );
value = replaceVariables( value, vars );
// and more
}
}