【问题标题】:Extending a class that is instantiated by another class扩展由另一个类实例化的类
【发布时间】:2013-05-24 17:23:51
【问题描述】:

我正在使用用于自动化软件的“宏”的 Java API。除其他外,该 API 具有类 Simulation(某种全局状态)和 FunctionManager。我无法修改这些类。

我想创建一个BetterFunctionManager 的类extends FunctionManager,因为后者缺少一些有用的功能。但是我不知道该怎么做,因为FunctionManager不能直接实例化。必须从Simulation获取,像这样:

Simulation simulation = getCurrentSimulation();
FunctionManager functionManager = simulation.getFunctionManager();

注意Simulation也不能直接实例化;它必须通过getCurrentSimulation() 获得(当前模拟由宏解释器在运行时确定)。

我不能沮丧;以下抛出 ClassCastException:

BetterFunctionManager betterFunctionManager = simulation.getFunctionManager();

如何构造BetterFieldFunctionManager

【问题讨论】:

  • 您可以创建一个包含Simulation 属性的类,然后按照自己的方式进入所有重新定义的方法。然后你可以让它返回你的BetterFunctionManager
  • FunctionManager 是否将您需要在BetterFieldFunctionManager 中的所有成员公开?还是您还需要访问受保护的成员?
  • @Andreas:是的,据我所知,我需要的一切都是公开的。
  • @Jean-FrançoisCorbett 我问的原因是看看您是否可以使用委托方法 :-) 这也是我的建议,因为下面的答案已经提出。

标签: java constructor extends


【解决方案1】:

你发现的是The Expression Problem,恐怕你用纯Java攻击它最合理的选择是StinePike提出的使用组合和委托

如果您有能力为任务选择工具,那么我建议您查看Clojure Protocols。他们为表达式问题提供了一个非常好的解决方案(请参阅此处的非常好的解释Solving the Expression Problem with Clojure),如果我没记错的话,如果您最终在 clojure 中编写您的解决方案,您可以将其编译成 java .class 并在您的java应用程序

【讨论】:

  • 感谢您为我的问题命名。您链接到的优秀文章。在某种程度上,很高兴知道这对每个人来说都是一个问题,而不仅仅是我无法解决这个问题!
【解决方案2】:

免责声明:我对设计还是很天真。只是一个建议。使用delegation design pattern

public class BetterFunctionManager{
    private FunctionManager fm;
    public  BetterFunctionManager(FunctionManager fm){
        this.fm = fm;
    }

    existingMethods(){
        fm.existingMethods();
    }

    newMethods(){
        // new implementation
    }
}

缺点:

需要封装FunctionManager的所有方法

优势:

其他地方无需更改。改变就好了

BetterFunctionManager betterFunctionManager = 
                 new BetterFunctionManager (simulation.getFunctionManager());

【讨论】:

  • 确实是个好主意,这种机制称为委托。 ;) 它应用了优先组合而不是继承的原则。
  • @Nicocube .. 谢谢。是的,它是委托模式... :) .... en.wikipedia.org/wiki/Delegation_pattern
  • 这是我已经实现的。我希望能够扩展而不是委托,因为我不想为所有existingMethods 编写包装器方法。但感谢您确认这是一种有效的前进方式。
  • 编写包装方法的需要确实有点乏味 - 如果您使用的是 Eclipse,有一个代码助手可以简单地检查所需的方法,Eclipse 会为您编写委托方法( Netbeans 和其他人可能存在类似的功能)。无论如何,在这种情况下使用委托是一种非常有效的方法。
【解决方案3】:

由于类结构,您的选择受到限制,那么创建一个 FunctionManagerUtility 类而不是 BetterFunctionManager 怎么样。在 FunctionManagerUtility 类中,您可以通过将 FunctionManager 对象作为输入来添加方法来添加有用的功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-19
    • 2016-01-07
    • 2013-07-04
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    • 2013-07-18
    • 1970-01-01
    相关资源
    最近更新 更多