如何在Java中隐藏静态变量

时间:2018-05-09 07:59:06

标签: java inheritance binding

我有三个使用相同方法的类,只有常量不同。所以我想要的是创建一个基类,它包含所有方法并添加三个仅包含常量变量的子类。由于动态绑定,看起来不可能这样做。请看一下例子:

public class Parent {
    static String MY_CONSTANT = "bla bla";
    public void printSomething() {
        System.out.println(MY_CONSTANT);
    }
}

public class Child extends Parent {
    static String MY_CONSTANT = "hello world";
}

public class Greetings {
    public static void main(String[] args) {
        Child hey = new Child();
        hey.printSomething();
    }
}

输出是“bla bla”,但我希望输出为“hello world”。

这个问题有解决方法吗?

5 个答案:

答案 0 :(得分:1)

您必须覆盖printSomething()方法:

public class Child extends Parent {
    static String MY_CONSTANT = "hello world";

    @Override
    public void printSomething() {
        System.out.println(MY_CONSTANT);
    }
}

但是,有一个返回静态变量值的方法可能更干净。然后你可以覆盖该方法,并从基类中调用它:

public class Parent {
    static String MY_CONSTANT = "bla bla";

    public String getConstant() {
        return Parent.MY_CONSTANT;
    }
    public void printSomething() {
        System.out.println(getConstant());
    }
}

public class Child extends Parent {
    static String MY_CONSTANT = "hello world";

    @Override
    public String getConstant() {
        return Child.MY_CONSTANT;
    }
}

public class Greetings {
    public static void main(String[] args) {
        Child hey = new Child();
        hey.printSomething();
    }
}

答案 1 :(得分:1)

  

如何在Java中隐藏静态变量?

这是你可以为变量做的所有事情:隐藏它们。虽然可以继承变量,但不能覆盖它们。

由于实际值是特定于类和静态的,因此在此方案中重用方法的唯一方法是使其获取参数:

public class Parent {
    static String MY_CONSTANT = "bla bla";

    public void printSomething(String something) {
        System.out.println(something);
    }

    //Essentially, Parent.MY_CONSTANT becomes just the default
    public void printSomething() {
        System.out.println(MY_CONSTANT);
    }
}

孩子可以选择发送的内容(覆盖基本上是重用API):

public class Child extends Parent{
    static String MY_CONSTANT = "hello world";

    @Override
    public void printSomething() {
        //MY_CONSTANT is hidden and has "hello world"
        super.printSomething(MY_CONSTANT); 
    }
}

上述设计允许来自测试类的调用行为可预测(或者更确切地说,直观地):

Child hey = new Child();
//Behaves as Child.
hey.printSomething();

编辑:由于getter是一个实例方法(可以理解为依赖于实例类型来读取正确的值),因此可以向子项公开字段或setter以及所有种类隐藏的内容将被完全抑制:

public class Parent {
    protected String myConstant = "bla bla";

    public void printSomething() {
        System.out.println(this.myConstant);
    }
}

孩子们只需要在初始化块中设置值:

public class Child extends Parent{
    public Child() {
        myConstant = "hello world";
    }
}

答案 2 :(得分:0)

public class Parent {

    static String MY_CONSTANT = "bla bla";

    public void printSomething() {
        System.out.println(Child.MY_CONSTANT);
    }
}

public class Child extends Parent{
        static String MY_CONSTANT = "hello world";

        @Override
        public void printSomething() {
            super.printSomething(); // definition define in parent class
        }
    }
public class LeapTEST {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here

            Child child = new Child();
            child.printSomething();
    }

}

答案 3 :(得分:0)

如果您想使用常量,则应将静态修饰符与最终修饰符结合使用。最终修饰符表示此字段的值不能更改(请查看相关部分中的link)。 (静态变量对于类的所有实例都是通用的。最终变量在第一次设置后不能更改。)

如果查看Java Language Specification

  

如果是,则可以使用限定名称访问隐藏字段   static,或使用包含的字段访问表达式   关键字super或强制转换为超类类型。

因此,您可以使用ClassName.myStaticVariable:

在类外引用静态变量

由于你应该以这种方式访问​​它们,所以也不必担心隐藏它们。

答案 4 :(得分:0)

我遇到了同样的问题,我的解决方案不是通过扩展像这样的枚举来扩展父类:

public enum MyEnum {
    PARENT("Parent constant"),
    CHILD("Child constant");
    private String myConstant;
    MyEnum(String s) {
        myConstant = s;      
    }

    public void printConstant(){
        System.out.println(myConstant);
    }
}

然后,调用所需枚举的printConstant方法,例如:

MyEnum.CHILD.printConstant();

当然,这是有限的,但是它适合我的情况,所以我希望它也能对某人有所帮助。