解释这个输出

时间:2014-03-23 05:10:01

标签: java inheritance getter-setter

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由于父类中的所有字段都存在于Child对象中,因此在Child对象中有两个共享相同名称(a)和getter和setter的字段,因此java如何解析此getter和父类中私有字段的setter方法?

2 个答案:

答案 0 :(得分:6)

getA()方法仅在超类中定义,并且只能访问超类的成员。它无法知道子类的a,因此子类的a不能影响它。

子类的成员a是私有的还是公共的是不相关的。如果在子类中声明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的{​​{1}}方法正在读取B类的getA()版本。

现在让我们看看如果a的{​​{1}}个版本为私有,会发生什么。

B

如果我们尝试编译,我们将收到编译器错误:

A

上面的实验似乎表明,每个类都会尝试通过查看自身或在类层次结构中找到第一个class B extends A { private int a = 20; } 来解析Demo.java:18: error: a has private access in B 。如果a可见a(意为apublic),则会返回它。如果protected不可见,那么它就不会编译。

答案 1 :(得分:0)

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

如果你在B类中覆盖getA(),输出将是20,因为它将变为" a"在B的背景下。

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

这意味着:你不应该直接设置/获取变量。请改用这些方法。如果需要默认值,则应按照您的方式设置变量。

相关问题