Является ли эта переменная экземпляра “скрытой” или нет?

#java

#java

Вопрос:

Как получается, что ссылка на скрытую переменную varIntA в методе не влияет на объект, на который ссылаются в параметрах метода? (Например, varIntB изменен?)

 //   Main.Java 
import main.MainClass;
import sub.SubClass;

public class Main {
    public static void main(String[] args) {
        SubClass objSC = new SubClass();
        System.out.println("n before - "   objSC);
        SubClass.subtract( objSC, 25);
        System.out.println("n after - "   objSC); 
    }
}

//  mainMainClass.java
package main;

public class MainClass {
    protected int varIntA = 100;
    protected int varIntB = 100;

    public String toString() { return "varIntA: "   varIntA   "   varIntB: "   varIntB; }
}

//   subSubClass.java  
package sub;
import main.MainClass;

public class SubClass extends MainClass {
     public int varIntA;  //  (The access level of varIntA has no effect.)

     static public void subtract( SubClass obj, int n) {
         System.out.println("n  varIntA = "   obj.varIntA   "  varintB = "   obj.varIntB);
         obj.varIntA -= n;
         obj.varIntB -= n;
         System.out.println("  varIntA = "   obj.varIntA   "  varintB = "   obj.varIntB);       
      }
}
  

Комментарии:

1. Какой результат вы ожидаете и почему , и чем это отличается от того, что вы видите?

2. Потому SubClass что не имеет toString() функции, поэтому MainClass.toString() вызывается, которая использует MainClass.varIntA .

3. @JohnnyMopp, вероятно, нет, именно поэтому. @OP Более того, переменная все равно будет доступна super в подклассе, все, чего вы достигли, — это две отдельные переменные (нет «затеняющих» переменных, только отсутствие окончательных, однозначных ссылок).

4. @Rogue Да, я отредактировал и удалил это слово 🙂

5. Извините. Я так увлекся попытками сделать отступ в коде, что забыл. OP из метода показывает, что varIntA изменяется от нуля до -25, что имеет смысл. OP из основного класса показывает, что varIntA остается на уровне 100. Я полагаю, существует только один объект, как может быть несоответствие? Спасибо!

Ответ №1:

Есть две varIntA переменные-члены. subtract Метод будет работать с varIntA in SubClass , но toString метод будет печатать значение varIntA in MainClass .

Переопределение varIntA в SubClass скрывает суперкласс varIntA от подкласса, но не от любого кода MainClass .

Поэтому, когда вы запускаете этот код, только varIntB в классе MainClass будет уменьшено на 25. Итак, в конце вы должны увидеть эту напечатанную строку:

 after - varIntA: 100   varIntB: 75
  

В varIntA SubClass итоге in будет иметь значение -25 .

Эта веб-страница довольно хорошо объясняет, что здесь происходит. См. Раздел «Что скрывает переменная?».

Комментарии:

1. ДА. Ты сводишь меня с ума! Сколько объектов создано? Если бы вы могли быстро объяснить, это было бы здорово. Или не могли бы вы указать мне на ресурс, который мог бы? Спасибо!

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

3. Смотрите Ссылку на документацию, которую я добавил в нижней части моего ответа.

4. Я читаю это сейчас. На первый взгляд кажется, что это указывает на объект. ссылки на поля должны быть согласованными, поскольку ссылочный тип должен быть подчиненным как в аргументе метода, так и в объявлении объекта. Но, возможно, она неявно передается методом toString(), унаследованным от Main? Я буду экспериментировать дальше. Еще раз спасибо.

5. PS Я должен был сказать, что toString() наследуется от MainClass .