从超类构造子类

时间:2013-01-18 22:48:43

标签: java casting subclass wrapper superclass

这完全在JBox2D(Java中)的上下文中。 World类使用函数创建Body实例。我正在尝试为Body添加更多东西给我的应用程序。在这个问题中,Body由ComplexClassWithLotsOfAPI表示。

这是一般性问题。我试图通过扩展类来为预制类添加更多功能。我希望做这样的事情:

class SomeMore extends ComplexClassWithLotsOfAPI{
    int myExtraInt;
    //A bit more API functions
}

所以我可以这样做:

SomeMore sm=new SomeMore();
sm.someOldAPI();
sm.butAlsoMyNewAPI();

问题是这个ComplexClassWithLotsOfAPI是由另一个我无法修改的类(原始上下文中的World类)创建的,所以我不是简单地自己创建它们(否则这会起作用)。由于我不得不从一个ComplexClassWithLotsOfAPI开始,我一直在寻找一种从SuperClass 构造一个SubClass的方法,而有很多例子 cast 一个SuperClass到子类(但这不适用于此)。以下是需要完成的功能示例:

public SomeMore create(...){ 
    ComplexClassWithLotsOfAPI ccwlao=myWorld.create(...);
    SomeMore sm;
    //??
    return sm;
}

包装的替代方法? 我最初的解决方案是将ComplexClassWithLotsOfAPI包装到我自己的类中。为了构造我的新类,我只需将旧类传递给我的新构造函数并继续:

class SomeMore{
    public ComplexClassWithLotsOfAPI ccwloa;
    int myExtraInt;
    public SomeMore(ComplexClassWithLotsOfAPI nccwloa){
        ccwloa=nccwloa;
        myExtraInt=0;
    }
    //A bit more API functions
}
public SomeMore create(...){ 
    ComplexClassWithLotsOfAPI ccwlao=myWorld.create(...);
    SomeMore sm=new SomeMore(ccwlao);
    return sm;
    //OR more simply
    //return new SomeMore(myWorld.create(...));
}

但是为了访问旧的API,我需要这样做:

SomeMore sm=new SomeMore();
sm.ccwloa.someOldAPI();
sm.butAlsoMyNewAPI();

我可能有点不合理,但这种功能很繁琐,并且会给那些不需要它的东西带来更多的复杂性。我的意思是,如果有人想添加更多功能,他们会将我的课程包装到另一个课程中,并且有3个课程的heirarchies来获取旧的API吗?另外,将旧类中的每个API包装到我的新类中会感觉很浪费(其中有很多)。

sm.someOldAPIButWrappedInMyClass(); //not desirable

我无法访问ComplexClassWithLotsOfAPI的java文件,只能访问已编译的类文件。我不能简单地强迫我修改旧课程(即使我可以,我也不愿意这样做)。我对java比较陌生,所以也许这不是最好/最合适的方法,但我还是找不到替代方法。

1 个答案:

答案 0 :(得分:1)

Eclipse可以构建一个委托类,它是某个类的子类(即Parent),并在一个字段(称为委托者)中保存一个“Parent”实例,并生成覆盖'Parent'中所有方法的方法在被委托者中调用相同的方法。然后,您可以添加自己的方法。

您可以从上下文菜单Source选项中执行此操作,生成委托方法。您必须拥有子类并使其扩展为“Parent”并且具有“Parent”类型的字段以使代码生成器工作。

以下是一个例子:

/** Example class delegating to a contained variable */
public class DelegatingComparator implements Comparator<String> {
    // Delegatee has to be present before letting Eclipse generate
    private Comparator<String> delegatee;

    /** My own method extends Comparator methods */
    public int compareToFoo(String o1) {
        return compare(o1, "foo");
    }

    /** Generated by Eclipse. Source > Generate getters and setters */
    public void setDelegatee(Comparator<String> delegatee) {
        this.delegatee = delegatee;
    }

    /** Generated by Eclipse. Source > Generate Delegate Methods */
    public int compare(String o1, String o2) {
        return delegatee.compare(o1, o2);
    }

    /** Generated by Eclipse. Source > Generate Delegate Methods */
    public boolean equals(Object obj) {
        return delegatee.equals(obj);
    }

}