【问题标题】:Strategy/Pattern to bypass a super() constructor绕过 super() 构造函数的策略/模式
【发布时间】:2013-05-23 12:21:47
【问题描述】:

又是我的旧版 Java 应用程序。我有一个核心类来处理应用程序中的许多重要逻辑。我们称它为 MyManager。 MyManager 继承自库中的一个类,我们称之为 TopManager。限制是您不能修改任何这些定义。

public class MyManager extends TopManager {

    public MyManager(String a, String b){ 
        super(a);
        initialize(b);
    }

    public MyManager(){
        this(null,null);
    }

    private void initialize(String b){
        //specific implementation
    }
}

public class TopManager {
    public TopManager(String s){ 
        //some implementation
    } 
}

我想创建一个具有所有 MyManager 功能但使用 TopManager 默认构造函数的类 CustomManager。

public class CustomManager extends MyManager
    public CustomManager(){

     //super(); NO should call TopManager constructor
    }

由于在 Java 中不可能,我正在寻找其他聪明的想法

【问题讨论】:

  • 创建一个参数构造函数,但不要在其中做任何事情,它可以充当默认构造函数
  • @greedybuddha super(String, String) 致电TopManager(String)
  • 我看不到TopManager有默认构造函数。
  • 没有参数的构造函数实际上调用了this(null)。没有所有代码来保持主题(继承)

标签: java constructor design-patterns superclass


【解决方案1】:

我正在寻找其他好主意

您是否考虑过使用 cglib 之类的东西?

这是一个相当粗略的想法,但我知道它可以在运行/加载时执行一些与代码生成/修改类相关的邪恶魔法(通常用于模拟/动态 aop 实现)。

我知道我的建议相当骇人听闻,但是一旦被您提到的那个遗留库逼入绝境,它似乎对您来说可能会很方便...

【讨论】:

    【解决方案2】:

    我想创建一个拥有所有 MyManager 的类 CustomManager 特点

    是的,使用作曲

    但使用TopManager默认构造函数。

    通过使用泛化

    class CustomManager extends TopManager { // have all properties of TopManager
    
      private MyManager myManager; // have all behaviours of MyManager by delegating the call
    
    }
    

    【讨论】:

    • 它的 HAS-A 东西,而不是 IS-A
    • 问题是你不能调用myManager.initialize(String),因为它是一个私有方法。
    • 一个私有方法无论如何都不能被调用,即使你扩展了这个类。所以没有问题。
    • @eternay 操作员正在尝试调用myManager.initialize(String) :)
    • 这是一个开始。是的,是他的 initialize() 部分做坏事,不应该在默认构造函数中。
    【解决方案3】:

    如果星星是正确的,您也许可以使用组合而不是继承。扩展TopManager 并实例化MyManager 以供内部使用。如果您在同一个包中定义类,您将能够访问包私有成员。这与扩展 MyManager 时的访问级别相同。

    【讨论】:

      【解决方案4】:

      在 java 中不可能做到这一点是有原因的。如果您设法绕过直接超类的调用构造函数,您实际上会创建无效实例。 CustomManager 的实例也是MyManager。如果MyManager 的构造函数没有被调用,它就不会被初始化。

      这意味着如果不向MyMaanger 报告您想要执行此操作,您将无法绕过它。 “报告”是什么意思?这意味着MyMaanger 应该知道您想要绕过它的正常初始化。您可以通过使用特殊的布尔标志公开构造函数来指示您是否需要正常初始化:

      public class MyManager extends TopManager {
          public MyManager(boolean skipInit) {
              this(false);
          }
          protected MyManager(boolean skipInit) {
              super();
              if(skipInit) {
                  return;
              }
              // init
          }
      }
      
      public class CustomManager extends MyManager {
           CustomManager() {
              super(true);
           } 
      }
      

      【讨论】:

      • 但他不能更改 TopManager 和 MyManager 的代码,据我了解。
      【解决方案5】:

      您的CustomManager 应该继承自TopManager 而不是MyManager

      【讨论】:

      • 不正确。 CustomManager 需要具有 MyManager 中存在的功能。
      猜你喜欢
      • 2018-05-06
      • 2013-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-06
      • 2012-03-26
      • 2014-03-17
      • 2012-12-30
      相关资源
      最近更新 更多