【问题标题】:java how to prevent class from being derived more than two levels?java如何防止类被派生超过两个级别?
【发布时间】:2012-08-08 23:32:36
【问题描述】:

在 java 中,我需要防止 Level1 类(请看下面的示例代码)派生超过两个级别。派生到 Level2 和 Level3 是可以的,但如果类是由 Level4 派生的,那么应该抛出异常。看下面的代码示例。

代码示例:

class Level1 {
    private int level = 1;

    protected Level1() throws RuntimeException {
        level++;
        //System.out.println(level);
        if (level > 2) {
            throw new RuntimeException("Can't implement more than 2 levels");
        }
    }
}

class Level2 extends Level1 {
    protected Level2() {
    }
}

class Level3 extends Level2 {
    Level3() {
    }
}

class Level4 extends Level3 {
    Level4() {
    }
}

从上面的代码示例中,我没有提出使用静态 int 级别计数器的解决方案。我只是想解释这个问题。

在 Java 中是否有可能通过实现一些逻辑或使用一些 API,其中 Level1 基类可以计算它已派生的级别数?

【问题讨论】:

  • 这背后的动机是什么?
  • 你应该解释这样做的动机,否则你的问题可能会被关闭。
  • Giant-mega-WTF-codesmell 这对一个古怪的设计大喊大叫。
  • 您在寻找工厂模式吗?这真是一个奇怪的要求.. 除了你记录最后一级的类来制作它们final
  • +1 表示“Giant-meta 等”当场。

标签: java inheritance


【解决方案1】:

您可以在构造函数中使用反射并遍历 this.getClass() 的继承链以查看嵌套级别。实际上 this.getClass().getSuperClass() == Level1.class 的测试应该已经可以解决问题了。

【讨论】:

  • 是的,这会很好用。反射应该被用作最后的手段......但是有非常有效的使用它的案例。
  • 但是如果派生类实现了它的构造函数而不调用super()呢?
  • @SJuan76:这在 Java 中是不可能的,你总是需要调用超级构造函数,只有字节码技巧可以解决这个要求
  • 好吧,你是对的。我的想法是,既然您可以显式调用super(),那么如果您不这样做,则不会调用父构造函数。如果构造函数中没有super()(带或不带参数),则Java添加它。
【解决方案2】:

introspection api 可以帮你解决这个问题,试试这样的:

protected Level1() throws RuntimeException {
        if (getClass().equals(Level1.class)) {
            return;
        }

        if (getClass().getSuperclass().equals(Level1.class)) {
            return; // first level or inheritance
        }

        if (getClass().getSuperclass().getSuperclass().equals(Level1.class)) {
            return; // second level or inheritance
        }
        // else
        throw new RuntimeException("Can't implement more than 2 levels");
    }

对了,你为什么要这么做?

【讨论】:

  • 可能这是一种错误的设计实践。讨论中出现了一个疯狂的想法,我们希望基类(在本例中为 Level1)控制它的派生方式,而不使用传统的 Java 编码方法,通过将类设为 final 或将类构造函数设为私有。感谢您的答案和代码解决方案。
【解决方案3】:

您可以查看 getClass().getSuperclass() 等来检查您的班级不超过 N 个级别。

然而,这是一个令人费解的要求。 :P

【讨论】:

    【解决方案4】:

    您可以将 level3 类设为 final,然后它不能被任何类扩展。声明为 final 的类不能被子类化。

    【讨论】:

      猜你喜欢
      • 2014-01-09
      • 2017-05-29
      • 1970-01-01
      • 2011-05-26
      • 2018-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-17
      相关资源
      最近更新 更多