【问题标题】:Why the value a in base class not changing?为什么基类中的值 a 没有改变?
【发布时间】:2021-09-14 18:25:00
【问题描述】:

所以我想了解继承在 java 中的工作原理。我想借助第二类中的方法来更新超类中 a 的值。我想使用第三类中的方法打印更新的数据。但是我没有得到更新的数据,尽管我使用第二类中的更新方法将其更改为 20,但我仍然得到 10 作为输出。为什么会这样?我该如何解决?

代码:

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();
    }
}

【问题讨论】:

  • 它确实改变了,但是你为你的 obj2 实例改变了它,而不是为 obj3。你了解静态和实例的区别吗?
  • 继承不是这样工作的,three 类是一个新实例,它对two 类在其实例中对a 做了什么一无所知。 two 类和 three 类具有不同的 a 实例。
  • 也许您想通过使用 protected 关键字使第一类中的变量 a 可由其子类访问?
  • @Stultuske 你能给我确切的代码吗?
  • @LuckBandit74 我想说最好的做法是将其设为私有并创建一个 setter 和 getter 方法来访问类外的属性。

标签: java variables inheritance


【解决方案1】:

Super 用于访问父类的变量或方法,它不能改变该类的原型。当您创建 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】:

    我认为您误解了这三个类之间的继承发生了什么。每次在您的示例中使用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 个对象 obj1obj2obj3。当您调用 print_changed_data() 时,obj1obj3 将始终打印出 10,因为您尚未使用新值更新 a。而在 obj2 上调用 update() 时,您将 obj2s a 的值更改为 20。

    看看这个简单的w3schools guide for inheritance

    【讨论】:

      【解决方案3】:

      类只是蓝图;他们没有任何存储空间。当您初始化一个类时,会创建一个包含所有所需变量的对象。 obj2obj3 只是内存中包含其单独变量的不同对象。 class twoclass three 之间没有“直接”连接。这两个类都使用class one 作为蓝图,但这不会在对象中的变量 (a) 之间创建关系。

      想象一家公司根据确切的蓝图制造汽车;这些车辆在技术上是相同的,但如果你启动一辆车,只有那辆实际的车会转弯。此精确蓝图中的所有其他车辆都不会启动;如果它们打开会很奇怪。

      【讨论】:

        猜你喜欢
        • 2017-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        • 2022-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多