Наследование Java - переопределение переменных экземпляра
Почему переменные экземпляра суперкласса не переопределены в наследовании?
Ответы
Ответ 1
Поскольку наследование предназначено для изменения поведения. Поведение выявляется с помощью методов и почему они могут быть переопределены.
Поля не являются поведением, а состоянием. Вам не нужно изменять это, а также частные методы, используемые суперклассом. Они предназначены, чтобы позволить суперклассу выполнять эту работу.
Ответ 2
Вы можете скрыть поле, но не переопределить.
Скрытие означает, что поле будет иметь другое значение в зависимости от того, к какому классу он обратился. Поле в подклассе "скроет" поле в суперклассе, но оба они существуют.
Это очень плохая практика, чтобы скрыть поле, но работает:
public class HideField {
public static class A
{
String name = "a";
public void doIt1() { System.out.println( name ); };
public void doIt2() { System.out.println( name ); };
}
public static class B extends A
{
String name = "b";
public void doIt2() { System.out.println( name ); };
}
public static void main(String[] args)
{
A a = new A();
B b = new B();
a.doIt1(); // print a
b.doIt1(); // print a
a.doIt2(); // print a
b.doIt2(); // print b <-- B.name hides A.name
}
}
В зависимости от того, был ли метод overriden, доступ к полю в A
или B
.
Никогда не делайте этого!. Это никогда не решение вашей проблемы и создает очень тонкие ошибки, связанные с наследованием.
Ответ 3
Потому что:
-
Он может сломать код parent class
. Например, рассмотрим следующий код (что будет поведение строки obB.getInt();
в следующем коде, если разрешено переопределение экземпляров):
class A
{
int aInt;
public int getInt()
{
return aInt;
}
}
class B extends A
{
int aInt;
public int getInt2()
{
return aInt;
}
public static void main(String[] args)
{
B obB = new B();
//What would be behavior in following line if,
//instance variables overriding is allowed
obB.getInt();
}
}
-
Это не логично, потому что child class
должно/отражать все поведение parent class
.
Таким образом, вы можете скрыть только унаследованные методы/переменные в child class
, но не могут override
.
Ниже приведен фрагмент из Java doc из Oracle, определяющий, какую операцию вы можете выполнять/ожидаете от child class
:
Вы можете использовать унаследованные элементы как есть, заменить их, скрыть их или дополнить их новыми членами:
- Унаследованные поля могут использоваться напрямую, как и любые другие поля.
- Вы можете объявить поле в подклассе с тем же именем, что и в суперклассе, тем самым скрывая его (не рекомендуется).