向Java类库添加函数

时间:2010-05-03 21:01:17

标签: java function casting class

我使用的Java类库在很多方面都是不完整的:我觉得应该有许多类内置其他成员函数。但是,我不确定添加这些成员函数的最佳实践。< / p>

让我们调用不充分的基类A

class A
{
    public A(/*long arbitrary arguments*/)
    {
        //...
    }

    public A(/*long even more arbitrary arguments*/)
    {
        //...
    }

    public int func()
    {
        return 1;
    }
}

理想情况下,我想向A添加一个函数。但是,我做不到。我的选择是:

class B extends A
{
    //Implement ALL of A's constructors here

    public int reallyUsefulFunction()
    {
        return func()+1;
    }
}

class AddedFuncs
{
    public static int reallyUsefulFunction(A a)
    {
        return a.func()+1;
    }
}

我看待它的方式,它们都有优点和缺点。第一种选择提供了比第二种选择更清晰的语法,并且更符合逻辑,但存在问题:假设我在类库中有第三个类C

class C
{
    public A func()
    {
        return new A(/*...*/);
    }
}

正如我所看到的,没有简单的方法可以做到这一点:

C c;
int useful = c.func().reallyUsefulFunction();

C.func()返回的类型为A,而不是B,您无法向下投射。

那么将成员函数添加到只读库类的最佳方法是什么?

4 个答案:

答案 0 :(得分:2)

为什么不使用Composition而不是Inheritance?

class ABetterA {
    private A a;

    public ABetterA() {

    }

    // write wrapper methods calling class' A methods and maybe doing something more
}

这样,你也可以模仿多重继承...

答案 1 :(得分:2)

自然而频繁的困境。阅读composition vs inheritance替代方案。如果我们认为对象A在构造函数中传递而不是在每个方法中传递它,那么你的第二个选择基本上是一个组合 - 也就是说,我们将使用组合来实现包装器或{{ 3}}模式。

只要C类决定承担创建新实例的责任,C类返回A类新实例的问题就没有任何简单的解决方案。这就是为什么在类中键入“new”语句之前应该暂停和思考的原因,如果有可能将该类子类化。在你的例子中,如果你能告诉C类要返回的具体类,那将会很好......但是如何创建它呢?好吧,我们可以向他传递一个知道如何实例化A类(或子类)对象的对象......我猜你现在已经足够有动力阅读decorator,并且通常会设计模式。

没有唯一的最佳答案,但如果想要一个快速的答案:我做一个包装器,B类不扩展A但是有一个带有A作为参数的构造函数,它将其方法(除了自己的)委托给内部对象。 当你需要在C类中调用该方法时(我假设你无法触及C类),你可以写:B b = new B(c.func())

答案 2 :(得分:1)

你有第三种选择。您可以使用Scala(一种Java兼容语言)及其traits,它们是mixins的其他名称。

答案 3 :(得分:0)

类似于Brian的另一个选择是使用面向方面编程(AOP)工具,例如 ApectJ ,它可以让您在现有类中“注入”其他功能,甚至是二进制的。您可以预处理库jar以获取具有增强类的新库(“静态编织”),也可以在加载库类时在运行时执行所有这些操作(所谓的“加载时编织”)。您可以查看AspectJ example

即使AOP通常用于修改现有方法(在“建议”之前,之后或周围=代码片段),您也可以引入新成员和方法 - 检查AspectJ's Inter-type declarations

当然,在您的有限平台上是否支持AspectJ存在问题。