Как скрыть статическую переменную в Java - PullRequest
0 голосов
/ 09 мая 2018

У меня есть три класса с одинаковыми методами, и только константы разные. Итак, я хотел создать один базовый класс, который содержит все методы, и добавить три дочерних класса, которые содержат только постоянные переменные. Похоже, что это невозможно сделать из-за динамического связывания. Пожалуйста, посмотрите на пример:

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 голосов
/ 16 июля 2019

Я столкнулся с той же проблемой, и мое решение вместо расширения родительского класса было с использованием перечисления, подобного этому:

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

Конечно, это ограничено, но подходит для моего случая, поэтому я надеюсь, что это кому-то тоже поможет.

0 голосов
/ 09 мая 2018

Если вы хотите использовать константу , вам следует объединить статический модификатор с final . Последний модификатор указывает, что значение этого поля не может измениться (см. Эту ссылку в соответствующем разделе). (Статическая переменная является общей для всех экземпляров класса. Конечная переменная не может быть изменена после того, как она была установлена ​​в первый раз).

Если вы посмотрите Спецификация языка Java :

Доступ к скрытому полю можно получить с помощью квалифицированного имени, если оно статический или с помощью выражения доступа к полю, которое содержит ключевое слово super или приведение к типу суперкласса.

Таким образом, вы можете ссылаться на статическую переменную вне класса, используя ClassName.myStaticVariable:

И так как вы должны получить к ним доступ таким образом, нет необходимости беспокоиться о том, чтобы скрыть их.

0 голосов
/ 09 мая 2018
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();
    }

}
0 голосов
/ 09 мая 2018

Как скрыть статическую переменную в 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();

РЕДАКТИРОВАТЬ: Поскольку метод получения является методом экземпляра (понятно, поскольку вы полагаетесь на тип экземпляра для чтения правильного значения), вы можете предоставить дочерним элементам поле или метод установки и все виды сокрытие будет полностью подавлено:

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";
    }
}
0 голосов
/ 09 мая 2018

Вам придется переопределить метод 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();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...