#java #variables #inheritance
Вопрос:
поэтому я пытаюсь понять, как именно наследование работает в java. я хочу обновить значение a в суперклассе с помощью метода второго класса. и я хочу распечатать обновленные данные, используя метод из третьего класса. Но я не получаю обновленные данные, я все еще получаю 10 в качестве выходных данных, хотя я изменил их на 20, используя метод обновления во втором классе. почему это происходит? как я могу это решить?
код:
class one{
int a=10;
}
class two extends one{
void update(){
super.a=20;
}
}
class three extends one{
void print_changed_data(){
System.out.println(super.a);
}
}
public class four{
public static void main(String[] args) {
two obj2=new two();
obj2.update();
three obj3=new three();
obj3.print_changed_data();
}
}
Комментарии:
1. он действительно изменился, но вы изменили его для своего экземпляра obj2, а не для obj3. Понимаете ли вы разницу между статикой и экземпляром?
2. Наследование работает не так, класс
three
-это новый экземпляр, который ничего не знает о том, что классtwo
сделалa
в своем экземпляре. Классtwo
и классthree
имеют разные экземплярыa
.3. Может быть, вы хотите сделать переменную a в классе one доступной для ее подклассов, используя ключевое слово protected?
4. @Stultuske вы можете дать мне точный код?
5. @LuckBandit74 Я бы сказал, что лучшей практикой было бы сделать его закрытым и создать сеттер и метод получения для доступа к свойству за пределами класса.
Ответ №1:
Супер используется для доступа к переменной или методу из родительского класса, он не может изменить прототип этого класса. Когда вы создаете obj3, он по-прежнему создается на основе исходного прототипа. Это то, с чем вы в конечном итоге сталкиваетесь в своем коде:
two obj2=new two();
// obj2 = {
// a = 10
// update()
// }
obj2.update();
// obj2 = {
// a = 20
// update()
// }
three obj3=new three();
// obj2 = {
// a = 20
// update()
// }
// obj3 = {
// a = 10
// print_changed_data()
// }
Вот лучший пример того, для чего используется super:
class one{
int a=10;
void update(){
a = 30;
}
}
class two extends one{
void update(){
a=20;
}
void print(){
// a = 10
System.out.println(a);
this.update(); // a = 20
System.out.println(a);
super.update(); // a = 30
System.out.println(a);
}
}
public class three{
public static void main(String[] args) {
two obj2=new two();
obj2.print();
// output
// 10
// 20
// 30
}
}
Ответ №2:
Я думаю, вы неправильно поняли, что происходит в наследовании между этими 3 классами. Каждый раз, когда вы создаете новый экземпляр класса, используя new
в своем примере, вы создаете новую переменную экземпляра, вызываемую a
в этом классе, которая начинается со значения 10. В классе Two
у вас есть вызываемый метод экземпляра update()
, который изменяет значение a
на 20, вызов этого метода будет обновляться только a
для экземпляра класса, в котором вы его вызываете; в этом случае obj2
.
class One{
int a=10;
void print_changed_data(){
System.out.println(a);
}
}
class Two extends One {
void update(){
super.a=20;
}
}
class Three extends One {
}
public class four{
public static void main(String[] args) {
One obj1 = new One();
obj1.print_changed_data(); // Prints 10
Two obj2 = new Two();
obj2.print_changed_data(); // Prints 10
obj2.update();
obj2.print_changed_data(); // Prints 20
Three obj3 = new Three();
obj3.print_changed_data(); // Prints 10
}
}
В приведенном выше примере я внес изменения в ваш код и создал 3 объекта obj1
, obj2
и obj3
. obj1
и obj3
всегда будет выводить 10 при вызове print_changed_data()
, потому что вы еще не обновили a
новое значение. В то время как при вызове update()
obj2
вы меняете obj2
a
значение s на 20.
Ознакомьтесь с этим простым руководством w3schools по наследованию
Ответ №3:
Классы-это просто чертежи; у них нет никакого хранилища. При инициализации класса создается объект со всеми необходимыми переменными. obj2
и obj3
являются просто разными объектами в памяти, содержащими их отдельные переменные. Между и нет «прямой» связи class two
class three
. Оба класса используются class one
в качестве схемы, но это не создает связи между переменными ( a
) в объектах.
Представьте, что компания строит автомобили по точному чертежу; технически автомобили одинаковы, но если вы заведете один автомобиль, повернется только этот реальный автомобиль. Все остальные транспортные средства по этому точному чертежу не заводятся; было бы странно, если бы они включились.