当一个子类继承一个超类时,子类和超类中定义的具有不同可访问性的字段是什么关系,哪个字段归子类所有,哪个不属于子类。有人可以解释下面的例子:
class Parent
{
private int partOne = 0;
public int partTwo = 1;
public void tellMe()
{
System.out.println(partOne);
System.out.println(partTwo);
}
}
class Child extends Parent
{
private int partOne = 2;
public int partTwo = 3;
public void main(String[] args)
{
Child child = new Child();
child.tellMe();
}
}
我在Eclipse中调试的时候,我观察了堆栈中的变量child,发现child实例有四个字段,两个由它的类定义,两个由它的父类定义,我非常困惑。我在创建子实例IMP时是否创建了一个父实例,我认为它只进入父类的构造函数,但我无法解释为什么子类不覆盖这两个字段,或者至少,我认为它应该覆盖partTwo与公共可访问性。请告诉我原因是什么,谢谢。
为什么子类不覆盖这两个字段,或者至少,我认为它应该覆盖具有公共可访问性的 partTwo
在 Java 中,数据成员不是多态的。这意味着在您的示例中,Child
类中定义的两个字段与Parent
类中的两个字段完全无关,即使它们碰巧共享其名称。
虽然这是语言允许的,但做这种性质的事情只是混淆的秘诀(正如你已经发现的那样)。
如果需要多态行为,请创建两个成员函数(getPartOne()
和 getPartTwo()
),并根据需要重写它们。
发生的情况是,通过在Child
类上使用相同的名称重新定义它来隐藏对Parent
类的字段partTwo
的访问。实际上,您应该从编译器那里收到有关此的警告。
执行以下实验以查看发生了什么:
- 向两个类添加一个适当的构造函数,在
Child
的构造函数上调用super
(是的,这不是必需的,但它可以帮助使事情更清晰)。
在 - 构造函数中初始化字段,而不是直接在字段声明中执行此操作。
- 到目前为止,代码将执行相同的操作。
- 现在从
Child
类中删除partTwo
变量 - 它仍将编译,但这次将应用Child
构造函数设置的值(警告将消失)。
您可能已经看到我发布的关于封装的评论 - 只有私有字段可以防止这种混淆,并允许以后更好地维护您的类,因为您可以更改类的字段而不影响继承类(只要访问数据的方法保持不变)。