2015-05-05 3 views
-4

Чтобы имитировать некоторые автоматически сгенерированные классы, которые выглядят так, я сделал небольшой тестовый класс jUnit для имитации наследования и скрытых полей.Наследование Java и скрытые общедоступные поля

public class ClassDerivationTest { 

    @Test 
    public void testChild() { 

     ChildClass child = new ChildClass(); 

     // Implicit boolean as it is hiding the super value 
     child.value = true; 

     // one way to update the parent value 
     // child.setParentVal("true"); 

     // child.super.value = "test"; 
    } 

    public class ChildClass extends ParentClass { 
     public boolean value; 
    } 

    public class ParentClass { 
     public String name; 
     public String value; 
    } 
} 

Мой вопрос: есть ли короткий путь, чтобы назначить супер класс value поле подобным образом, как это:

child.super.value = "test"; 

вместо того, чтобы создать определенную сеттер в ChildClass:

// Imagine this method is not existing for the question 
    public void setParentVal(String val) { 
     super.value = val; 
    } 

Я использую Java 7, и мне интересно, можно ли было бы без изменения ChildClass или ParentClass (вроде бы это могло быть автоматически сгенерированным кодом).

UPDATE: Я знаю, что вы есть несколько способов управления этим путем а) Литье по ответам Йона: ((ParentClass) child).value = "test";, но не очень хорошо б) создании экземпляра супер класс, как это (как можно больше): ParentClass myInstance = new ChildClass(); код myInstance.value будет ссылаться на поле в ParentClass

Но я хотел быть более сосредоточены на новых возможностях Java 8. Например можно ли решить эту проблему с лямбда, или другой новой функции Java 8?

+0

Строго ли нужно, чтобы их называли одной и той же? Я думаю, что правильное решение для дочернего класса, которое хочет установить родительские элементы, должно было бы не переопределять их в первую очередь. – Thomas

+8

Вы не переопределяете родительское поле. Ты скрываешь это. Полиморфизм работает только с методами. Не с полями. Использование публичных полей - очень плохая практика. Только не делай этого. –

+1

@JBNizet Это плохая практика, если вы не назовете ее «Объектом передачи данных» и не создадите шаблон. Вы видите, если вы используете фасоль и имеете глупые геттеры и сеттеры для этих ... в чем существенное отличие от доступа к полю? Просто теоретическая возможность изменить сеттер в какой-то более поздний момент времени. – GhostCat

ответ

7

Ну вы можете просто бросить child, чтобы компилятор решить поле value относительно ParentClass вместо ChildClass:

((ParentClass) child).value = "test"; 

Но, честно говоря, я бы а) избежать не-приватные поля; b) избегать сознательного предоставления полей суперклассов и подклассов с тем же именем.

В отличие от вашего комментария поле подкласса не «переопределяет» поле суперкласса - оно скрывает его.

+0

@JoopEggen: Inheritance * is * участвует ('ChildClass расширяет ParentClass'), но я согласен с тем, что поле подкласса скрывает родительский один - и я только что написал редактирование на этот счет. –

+0

Почему следует избегать «защиты»? Я могу понять «публичный», но просто любопытно, что «защищенный» также избегается. – CKing

+0

@ChetanKinger: IMO, поля - это детали реализации, которые должны быть ограничены самим классом. Если я захочу позже изменить эту реализацию (переименуйте поле, измените его тип), я должен это сделать, не нарушая подклассы. –