我有一个代码:
class Parent{
int x=10;
void show(){
System.out.println(x);
}
}
class Child extends Parent{
int x=20;
public static void main(String[] args){
Child c=new Child();
c.show();
}
}
这里当我运行这个程序时,输出结果为10.这意味着在运行时父成员函数不使用具有相同名称的Child数据成员(数据隐藏)。我知道的是,每当我们扩展一个类时,它的父类成员函数和数据成员都可用于Child类,那么当我说c.show()
为什么它需要父类的数据成员而不是Child类。另外,我想知道当我们创建Child类的对象时,它的Parent类数据成员被放在Heap中Child类对象的Parent部分中,但成员函数会发生什么?
答案 0 :(得分:5)
我知道的是,每当我们扩展一个类时,它的父类成员函数和数据成员都可用于Child类,那么当我说c.show()时为什么它需要Parent类的数据成员不是儿童班。
你的理解正确。但其他情况并非如此。父类子对象无权访问子类子对象。由于show()
在基类Parent
的范围内,因此它正在访问它自己的成员。尝试评论父类中的成员x
,看看你的程序是否编译。
答案 1 :(得分:4)
通过简单地声明其自己的字段版本,子项无法从父类中的方法隐藏字段。您正在反过来应用“数据隐藏”的想法。孩子永远不能隐藏父母的字段,但父母可以隐藏孩子的字段(通过将x
声明为private
)。如果您愿意,可以use encapsulation to achieve your desired effect,例如:
class Parent{
private int x=10;
public int getX() {
return x;
}
void show(){
System.out.println(this.getX());
}
}
class Child extends Parent{
int x=20;
@Override
public int getX() {
return x;
}
public static void main(String[] args){
Child c=new Child();
c.show();
}
}
通过覆盖getX()
访问者方法,孩子可以隐藏父母与世界其他地方的x
的值。
其他一些值得讨论的观点:
我所知道的是,每当我们将一个类扩展为它的父级时 类成员函数和数据成员可用于Child类
这不完全正确。私有方法和数据成员不会(直接)可用于子类。子类只能直接访问公共,受保护和“包级”方法和字段。
另外,我想知道当我们创建一个Child类的对象时 父类数据成员放在Child类的Parent部分中 Heap中的对象,但成员函数会发生什么?
不会按实例创建成员函数。如果JVM像那样工作,那将是非常低效的。相反,给定类的方法实现只定义一次,作为Permanent Generation
的一部分,它包含类定义和其他内部JVM状态。给定类的所有实例将共享相同的方法定义。
对于子类,它将共享其父类的方法定义,并且它还将为子类中存在的任何方法(以及它覆盖的任何方法)添加自己的定义。 / p>
答案 2 :(得分:1)
子进程中的X只影响基类,而不是覆盖它。基类成员变量不会被更改,只会被恰好具有相同名称的子类中的单独变量隐藏。他们仍然是完全不同的变数。