Переопределение переменных экземпляра суперкласса

Почему мы не можем переопределить переменную экземпляра суперкласса в подклассе?

9 ответов

Решение

Потому что, если вы измените реализацию элемента данных, вполне возможно, что он сломает суперкласс (представьте, что нужно изменить элемент данных суперкласса с плавающей на String).

Возможно, он хотел попытаться переопределить значение, используемое для инициализации переменной. Например,

Вместо этого (что незаконно)

public abstract class A {
    String help = "**no help defined -- somebody should change that***";
    // ...
}
// ...
public class B extends A {
    // ILLEGAL
    @Override
    String help = "some fancy help message for B";
    // ...
}

Надо делать

public abstract class A {
    public String getHelp() {
        return "**no help defined -- somebody should change that***";
    }
    // ...
}
// ...
public class B extends A {
    @Override
    public String getHelp() {
        return "some fancy help message for B";
    // ...
}

Потому что вы можете только переопределить поведение, а не структуру. Структура устанавливается в камне после того, как объект был создан и для него выделена память. Конечно, это обычно верно в статически типизированных языках.

Переменные не доступны полиморфно. Что бы вы хотели сделать с этим, что вы не можете сделать с защищенной переменной? (Не то чтобы я вообще поощрял использование непубличных изменяемых переменных).

class Dad{
    public String name = "Dad";
}
class Son extends Dad{
    public String name = "Son";
    public String getName(){
        return this.name;
    }
}

Из метода main(), если вы вызываете

new Son().getName();

вернет "Сын". Так вы можете переопределить переменную суперкласса.

Вы имеете в виду, что при переопределении вы хотите изменить тип данных, например?

Что вы делаете с этим выражением

public class A {
   protected int mIndex;

   public void counter(){
      mIndex++;
   }

}

public class B extends A {
   protected String mIndex; // Or what you mean with overloading
}

Как вы хотите изменить выражение mIndex++ без перегрузки операторов или что-то вроде этого.

Мы не можем переопределить структуру переменных экземпляра, но мы переопределяем их поведение:

class A
{
int x = 5;
}

class B extends A
{
int x = 7:
}

class Main
{
public static void main(String dh[])
{
A obj = new B();
System.out.println(obj.x);
}
}

в этом случае вывод равен 5.

Если вам нужно переопределить переменную экземпляра, вы почти наверняка наследуетесь от класса worng.

В некоторых языках вы можете скрыть переменную экземпляра, указав новую:

class A has variable V1 of type X;

class B inherits from A, but reintroduces V1 of type Y.

Методы класса A все еще могут получить доступ к исходному V1. Методы класса B могут получить доступ к новому V1. И если они хотят получить доступ к оригиналу, они могут привести себя к классу А (как вы видите, грязное программирование провоцирует более грязное программирование).

Лучшее решение - найти другое имя для переменной.

Вы можете переопределить метод, это нормально, но что вы подразумеваете под переопределением переменной? если вы хотите использовать переменную в любом другом месте, а не в суперклассе, вы можете использовать супер. как в супер (имена переменных); почему вы хотите переопределить переменную? Я имею в виду, есть ли необходимость?

Другие вопросы по тегам