Java 在通用抽象方法的所有子类中提取通用实现的最佳方法

Java 在通用抽象方法的所有子类中提取通用实现的最佳方法,java,inheritance,abstract-class,Java,Inheritance,Abstract Class,我有一个抽象类,不幸的是我不能更改它的定义,它基本上提供了一个抽象方法,有点像 public abstract void do(Data someData, BaseInterface interface); public void do(Data someData, BaseInterface interface) { CastTheBaseInterface obj = (CastTheBaseInterface) interface; obj.exec(someData)

我有一个抽象类,不幸的是我不能更改它的定义,它基本上提供了一个抽象方法,有点像

public abstract void do(Data someData, BaseInterface interface);
public void do(Data someData, BaseInterface interface) {
    CastTheBaseInterface obj = (CastTheBaseInterface) interface;
    obj.exec(someData);
}
现在,每个类都需要实现这个抽象方法,有点像

public abstract void do(Data someData, BaseInterface interface);
public void do(Data someData, BaseInterface interface) {
    CastTheBaseInterface obj = (CastTheBaseInterface) interface;
    obj.exec(someData);
}

现在,我可以转换接口了,但是我必须大量扩展这个抽象类,并且每次都要进行转换,而转换将在同一个实现上进行,即CastTheBaseInterface。我正在考虑在我的类和超级抽象之间引入另一层,并解决这个问题。但无法想出解决办法。我的观点是,如果我事先知道接口将被转换到哪个实现中,为什么要再做一次&再做一次。

如果不使用Java 8或更高版本,请创建另一个抽象类,该抽象类派生您无法修改的抽象类,并在这个新的抽象类中实现该方法。
然后使子类实现新的抽象类

若您使用Java8或更高版本,请创建一个接口,在该接口中声明具有公共处理的默认方法。然后让您的子类实现这个接口和抽象类。因此,您不需要在子类中再次实现它


这些解决方案并不“漂亮”,但您有遗留约束,因此应该可以接受。

以下是一个解决方案,适用于只有一个实现要强制转换的情况:

public class YourNewAbstractClass extends LegacyAbstractClass {
    @Override
    public void do(Data someData, BaseInterface interface) {
        CastTheBaseInterface obj = (CastTheBaseInterface) interface;
        doCasted(someData, obj );
    }

    public abstract doCasted(Data someData, CastTheBaseInterface interface)
}
那么您的子类将如下所示:

public class ChildClass extends YourNewAbstractClass {
    @Override
    public void doCasted(Data someData, CastTheBaseInterface casted) {
        casted.exec(someData);
    }
}
public class ChildClassOne extends YourNewAbstractClass<CastTheBaseInterface> {
    @Override
    public void doCasted(Data someData, CastTheBaseInterface casted) {
        casted.exec(someData);
    }
}

public class ChildClassTwo extends YourNewAbstractClass<AnotherCastTheBaseInterface> {
    @Override
    public void doCasted(Data someData, AnotherCastTheBaseInterfacecasted) {
        casted.doSomeOtherStuff(someData);
    }
}
如果您有更多的实现,您可以使用暗魔法,这意味着使用泛型和动态强制转换相结合:

public class YourNewAbstractClass<T extends BaseInterface> extends LegacyAbstractClass {
    @Override
    public void do(Data someData, BaseInterface interface) {
        // getting the generic parameter that you will define in a subclass
        Class<T> clazz = (Class<T>) ((ParameterizedType) getClass()
                        .getGenericSuperclass()).getActualTypeArguments()[0];
        // dynamically casting your object to a generic type
        T casted = clazz.cast(something);
        doCasted(someData, casted);
    }

    public abstract doCasted(Data someData, T casted)
}
public类YourNewAbstractClass扩展了LegacyAbstractClass{
@凌驾
公共void do(数据someData、BaseInterface接口){
//获取将在子类中定义的泛型参数
Class clazz=(Class)((ParameterizedType)getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
//动态地将对象强制转换为泛型类型
T casted=clazz.cast(某物);
doCasted(一些数据,铸造);
}
公共摘要文件(数据部分数据,T铸造)
}
那么您的子类将如下所示:

public class ChildClass extends YourNewAbstractClass {
    @Override
    public void doCasted(Data someData, CastTheBaseInterface casted) {
        casted.exec(someData);
    }
}
public class ChildClassOne extends YourNewAbstractClass<CastTheBaseInterface> {
    @Override
    public void doCasted(Data someData, CastTheBaseInterface casted) {
        casted.exec(someData);
    }
}

public class ChildClassTwo extends YourNewAbstractClass<AnotherCastTheBaseInterface> {
    @Override
    public void doCasted(Data someData, AnotherCastTheBaseInterfacecasted) {
        casted.doSomeOtherStuff(someData);
    }
}
公共类ChildClassOne扩展了您的新抽象类{
@凌驾
public void doCasted(数据someData,CastTheBaseInterface casted){
casted.exec(someData);
}
}
公共类ChildClass2扩展了您的NewAbstractClass{
@凌驾
已存档的公共无效数据(部分数据,另一部分为基本接口已存档){
铸造。doSomeOtherStuff(someData);
}
}

希望这有帮助

do
interface
是关键字,不能用作名称“vent”-我不认为它的意思与您认为的意思相同。如果在每个子类中对强制转换对象调用的方法不同,例如,在强制转换之后,obj.exec、obj.exec1等等,这会起作用吗,因此,从第一次尝试开始,它可能就不起作用,但我想这个想法应该很清楚