【问题标题】:Explain this output解释这个输出
【发布时间】:2014-03-23 05:10:00
【问题描述】:
class A {
    private int a = 10;

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;       
    }    
}

class B extends A {
    public int a = 20;
}

public class Demo {
    public static void main(String args[]) {
        B a = new B();
        System.out.println(a.getA());        
    }
}

输出:10
由于父类中的所有字段都存在于子对象中,因此子对象中有两个共享相同名称(a)和getter和setter的字段,那么java如何解析这个getter和setter父类中私有字段的方法?

【问题讨论】:

    标签: java inheritance getter-setter


    【解决方案1】:

    getA() 方法只定义在超类中,并且只能访问超类的成员。它无法知道子类的a,因此子类的a 无法对其进行遮蔽。

    子类的成员a 是private 还是public 不相关。如果您在子类中将 a 声明为私有,您将看到相同的行为。

    更新:这里试图回答更一般的问题:在父类和子类中定义的成员如何解决?

    考虑 OP 示例的以下扩展:

    class A {
        public int a = 10;
    
        public int getA() {
            return a;
        }
    
        public void setA(int a) {
            this.a = a;       
        }    
    }
    
    class B extends A {
        public int a = 20;
    }
    class C extends B {
        public int getA() {
            return a;
        }
    }
    
    public class Demo {
        public static void main(String args[]) {
            B a = new B();
            System.out.println(a.getA());        
    
            C c = new C();
            System.out.println(c.getA());        
        }
    }
    

    在这里,我们看到1020 的输出,这意味着C 类的getA() 方法正在读取B 类的a 版本。

    现在让我们看看如果我们将BA 版本设为私有会发生什么。

    class B extends A {
        private int a = 20;
    }
    

    如果我们尝试编译,我们会得到一个编译器错误:

    Demo.java:18: error: a has private access in B
    

    上面的实验似乎表明每个类都将尝试通过查看自身来解析a,或者沿着类层次结构向上直到找到第一个a。如果 a 对它可见(意思是 publicprotected),那么它将返回它。如果 a 不可见,那么它根本无法编译。

    【讨论】:

    • 是的,谢谢您的回答。但我的问题是关于 getter 方法和两个字段 a(如果你调试代码,你可以看到有两个名为 a 的变量)是否存在于子对象中,如何调用父类 a解决机制是什么?
    • @KalhanoToressPamuditha,我还没有找到这方面的文档,但我做了一个快速的实验。让我更新我的答案。
    • @KalhanoToressPamuditha,我认为你的评论被切断了。如果问题是关于html 我建议你问一个新问题。 :P
    • :p , @merlin2011 能否请您向我解释一下,考虑子对象,它包括来自父对象和a 的 getter 和 setter 方法,当调用 getter 方法时它是如何从父母那里解决a 后面发生了什么?
    • @KalhanoToressPamuditha,子类的对象将首先使用自身的 getter 和 setter 方法。如果这些没有定义,它会在超类中查找,然后是超超类。
    【解决方案2】:

    当您调用 getA() 时,您正在调用 A 的方法,该方法将返回 A 的变量值。

    如果您在 B 类中覆盖 getA(),则输出将为 20,因为它将在 B 的上下文中获取变量“a”。

    如果您从类 B 的对象调用 setA,它将仅反映 A 的属性。即使你直接设置了 B 的变量(因为是 public),结果仍然是 10。

    这意味着:您不应该直接设置/获取变量。改用这些方法。如果你想要一个默认值,你应该像你一样设置一个变量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-12
      相关资源
      最近更新 更多