#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 .