在 Java 中设置子类所需的常量的最佳实践是什么?

DVK*_*DVK 0 java inheritance

我有以下情况:

  • 父类有一个依赖于常量的函数。但是定义该常量的唯一有效位置是在子类中(父类不能定义常量的值,但它可以在 99% 的用例中与未定义的常量一起使用 - 如果特定的配置元素是丢失的)。

  • 但是,我想强制从该父类继承的任何子类都必须定义常量的值,因为任何子类都必须能够使用其他 1% 的功能。

在 Java 中实现这种强制执行的最佳实践是什么,最好是在编译时?(显然,在运行时,我可以简单地检查使用它的方法中的常量是否为空/空)。

我自己的解决方案是在父类中为常量实现一个 value-getter 作为抽象方法,并在构造函数中结合真正的 setter 调用它;像这样:

   public class HelperClass1 {
       private String myConstant; 
       public void setMyConstant() {} // implemented obviousy
       public void myMethod() { // Called from ParentClass's methods
           // Do something useful with myConstant
       }
    }

   import HelperClass1;
   public abstract class ParentClass {
       ParentClass() {
           HelperClass1.setMyConstant( getMyConstantValue() );
       }

       public abstract void getMyConstantValue();
   }

   public class ChildClass1 extends ParentClass {
       public void getMyConstantValue() { return "BUZZ"; }
   }

   public class ChildClass2 extends ParentClass {
   }  // Fails to compile without getMyConstantValue()
Run Code Online (Sandbox Code Playgroud)

但是,(a) 这个实现有一个问题(我不能使用 ParentClass 本身,因为它现在是抽象的)没有子类化;(b) 由于我不是 Java 开发人员,恐怕这不是最好或最优雅的解决方案。所以我想知道是否有一种最佳实践方法可以改进我实施的内容。

Ken*_*ter 5

为父类提供两个构造函数:

  1. 一个是受保护的构造函数,它将常量作为参数。

  2. 另一个是私有构造函数,它可以在不设置常量的情况下构造父类的实例。

为可以调用私有非常量构造函数的父类提供一个工厂方法。

想要获取父类实例的类可以调用工厂方法。但是想要从父类继承的子类必须调用受保护的构造函数,它可以验证是否传递了有效的常量。

public class ParentClass {

    private final SomeClass myConstant;

    protected ParentClass(SomeClass aConstant) {
        if (null == aConstant) {
            throw new IllegalArgumentException("...");
        }
        myConstant = aConstant;
    }

    private ParentClass() {
        myConstant = null;
    }

    public static ParentClass getInstance() {
        return new ParentClass();
    }
}


public class ChildClass {

    public ChildClass() {
        super(new SomeClass(42));
    }
}
Run Code Online (Sandbox Code Playgroud)

这并不完美。有人可以编写一个将错误常量传递给超类构造函数的子类,并且在某些代码尝试构造子类的实例之前它实际上不会失败。