向Java类库添加函数

向Java类库添加函数,java,function,casting,class,Java,Function,Casting,Class,我使用的Java类库在很多方面都是不完整的:我觉得有很多类应该内置额外的成员函数。但是,我不确定添加这些成员函数的最佳实践 让我们调用不足的基类A class A { public A(/*long arbitrary arguments*/) { //... } public A(/*long even more arbitrary arguments*/) { //... } public int f

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

让我们调用不足的基类
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;
    }
}

在我看来,它们都有优点和缺点。第一个选项的语法比第二个选项更清晰,逻辑性更强,但也有问题:假设我在类库中有第三个类,
C

class C
{
    public A func()
    {
        return new A(/*...*/);
    }
}
在我看来,要做到这一点并不容易:

C c;
int useful = c.func().reallyUsefulFunction();
由于
C.func()
返回的类型是
A
,而不是
B
,因此不能向下转换


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

您还有第三个选择。您可以使用Scala(一种与Java兼容的语言)及其别名。

为什么不使用组合而不是继承

class ABetterA {
    private A a;

    public ABetterA() {

    }

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

这样,您还可以模拟多重继承…

自然和频繁的困境。阅读关于替代方案的信息。第二种选择基本上是组合,如果我们认为对象a在构造函数中传递,而不是在每个方法中传递——也就是说,我们将使用组合来实现包装器或模式

正如您所猜测的,只要类C决定负责创建新实例,类C返回类a的新实例的问题就没有简单的解决方案。这就是为什么在类中键入“new”语句之前,如果该类有可能被子类化,那么应该暂停并思考。在你的例子中,如果你能告诉C类返回什么具体的类,那就太好了。。。但它怎么知道要创造它呢?我们可以给他一个对象,他知道如何实例化类A(或子类)的对象。。。我想你现在已经有足够的动力去阅读关于设计模式的文章了

没有唯一的最佳答案,但如果想要一个快速的答案:我要做一个包装器,B类不扩展a,而是有一个带有a作为参数的构造函数,它将其方法(除了自己的)委托给内部对象。
当您需要在类C中调用该方法时(我假设您不能接触类C),您可以编写:
bb=newb(C.func())
另一个类似于Brian建议的选项是使用面向方面编程(AOP)工具,例如ApectJ,它允许您“注入”向现有类(甚至二进制类)中添加附加功能。您可以对库jar进行预处理,以获得一个带有增强类的新jar(“静态编织”),也可以在运行时加载库类时执行所有这些操作(所谓的“加载时编织”)。你可以检查一下

即使AOP通常用于修改现有方法(在“advices”=代码段之前、之后或周围),您也可以引入新成员和方法-检查


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

不幸的是,我没有这个选项。我正在为机器人平台(LeJOS NXJ)使用Java子集。@Eric:通常在Java中,函数被称为“方法”,即使它们是函数:)我接触类C的唯一方法是从它派生另一个修改过的类,这样做很快会使代码无法读取。有没有一种简单的方法使
B
扩展
A
,并给它一个以
A
为参数的构造函数?没有,你在这里混合了东西(确切地说是组合和继承)。继承和装饰器(通过组合实现)以及两种可以“接触”类的替代方法(即向类添加行为状态)。如果你读过这篇文章,你会发现继承常常被OOP新手高估了。
class ABetterA {
    private A a;

    public ABetterA() {

    }

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