【问题标题】:How to handle additional cases in subclass constructor?如何处理子类构造函数中的其他情况?
【发布时间】:2016-10-21 11:44:45
【问题描述】:

我有一个 java 类。

Class ClassA {
    ClassA(int type)
    {
        switch(type)
        {
            case 1: handleType1(); break;
            case 2: handleType2(); break;
            default: throw new IllegalArgumentException(); break;
        }
    }

    private void handleType1(){}
    private void handleType2(){}
}

现在我必须添加对类型 3 和类型 4 的支持。但是我不能修改 ClassA 的代码。

所以我想我会编写 ClassB 来扩展 ClassA 并添加对 type3 和 type 4 的支持,如下所示。

Class ClassB extends ClassA{
    ClassB(int type)
    {
        case 3: handleType3(); break;
        case 4: handleType4(); break;
        default:
        {
            try{
                /* To support type 1 and type 2. */
                super(type);
            } catch(IllegalArgumentException e) {
              /* Handle exception. */
            }
        } break;
    }

    private void handleType3(){}
    private void handleType4(){}
}

我认为这会奏效。但是我在 ClassB 的构造函数中得到了“Call to super() must be first statement in constructor body”错误。

我阅读了this post 并理解为什么 super() 必须是构造函数中的第一个语句。

我可以通过在 ClassB 中编写 ClassA 的完整代码并添加对类型 3 和 4 的支持来解决我的用例。但我想知道是否有更好的解决方案来解决这个问题。

【问题讨论】:

  • 遇到这样的疑惑,我觉得app架构有问题……

标签: java inheritance constructor


【解决方案1】:

现在我必须添加对类型 3 和类型 4 的支持。但是我不能修改 ClassA 的代码。

那么ClassB 不能合理地继承ClassA。子类必须调用父类构造函数。 (它可能子类化的不合理方式是通过传入不同的类型来欺骗ClassA 构造函数。)

理想情况下,ClassAClassB 都将实现一个接口,并且应用程序的其余部分将被编码为使用该接口,而不是专门使用 ClassAClassB

【讨论】:

    【解决方案2】:

    父类必须在初始化子类期间正确初始化(通过显式或隐式调用父类构造函数),但在您的情况下,父类不能用类型 3 和 4 初始化(以及也没有类型)。

    【讨论】:

      【解决方案3】:

      你有一个严重的设计缺陷。

      开关通常是一个强烈的信号,表明您应该使用接口多态

      您当前在A 的构造函数中的代码应该在一个工厂 类中,并且应该有一个接口的实现,为每个handleTypeX 声明通用方法

      【讨论】:

        猜你喜欢
        • 2021-10-29
        • 1970-01-01
        • 2022-12-21
        • 1970-01-01
        • 2017-04-01
        • 1970-01-01
        • 2019-03-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多