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

时间:2015-04-13 22:27:11

标签: java inheritance

我有以下情况:

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

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

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

我自己的解决方案是将常量的值获取器实现为父类中的抽象方法,并将其与构造函数中的实际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开发人员,我担心这不是最佳或最优雅的解决方案。所以我想知道是否有一种最佳实践方法可以改善我实施的内容。

2 个答案:

答案 0 :(得分:4)

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

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

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

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

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

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

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

答案 1 :(得分:-1)

您可以使用Enum和Interface:

来完成
       public interface CommonInterface {

            public String getValue();

        }

        public enum EnumImp implements CommonInterface {

            FIRST_EL("buzz"),
            SECOND_EL("hello"),
            THIRD_EL("hi");

            private final String element;

            private EnumImp(String element) {
                this.element = element;
            }

            public String getElement() {
                return this.element;
            }
        }


        public abstract class ParentClass {

            private CommonInterface _commonIntf;

            /**
             * 
             */
            public ParentClass(CommonInterface commonIntf) {
                _commonIntf = commonIntf;
            }

            //Example method that will be inherit
            public void invokeCommonInterface() {
                _commonIntf.getValue();
            }

        }