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

标签 java inheritance

我有以下情况:

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

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

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

我自己的解决方案是在父类中将常量的值 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()

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

最佳答案

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

  1. 其中一个是 protected 构造函数,它将常量作为参数。

  2. 另一种是私有(private)构造函数,可以构造父类的实例,而无需设置常量。

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

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

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));
    }
}

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

关于java - Java 中设置子类所需常量的最佳实践是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29616121/

相关文章:

java - 构建相机应用程序 - 接收

java - 我在一个 fragment 中有 2 个 RecyclerViews。但只显示第一个

Java:大规模并发方法调用对性能的影响

c++ - 在 C++ 中调用母类 operator= 的常用方法?

c# Entity Framework 选择派生子项

java - Selenium Webdriver - 无法使用 css 或 xpath 进行搜索,但可以使用 'by id' 或 'by class' 进行搜索

java - 带 ArrayBlockingQueue 的 ThreadPoolExecutor

java - 在@MappedSuperclass 的属性上使用@NamedEntityGraph

c++ - 多态和继承打印

c# - 为什么使用接口(interface),类和继承有什么问题