我一直在研究这个问题,我无法找到解决方案。
private abstract class Node {
private Rectangle bounds;
}
private class LeafNode extends Node {
private Rectangle bounds;
....
}
private class InternalNode extends Node{
private Rectangle bounds;
....
}
所以我得到一个空指针错误,所以我在eclipse中经历了调试器。但令我困惑的是eclipse,它显示有两个边界字段,我很确定我正在访问null字段,而不是我实际设置的字段。
当我在调试器中时,有时我会看到第一个使用的边界变量,有时我看到第二个被使用。我能想到的唯一可能的事情是,在整个代码中,我使用LeafNode和InternalNode进行一些转换。那么两个边界变量可以与我正在使用的抽象类链接吗?
答案 0 :(得分:1)
查看与字段阴影相关的主题。
简而言之,没有"覆盖"用于Java中的成员变量。如果在子类中声明一个与父类相同名称的成员变量,则子成员变量为" shadowing"父母的。
使用您的代码作为示例,在LeafNode
实例中,实际上有两个成员变量称为bounds,您可以将其视为" Node :: bounds"和" LeafNode :: bounds"。
如果您通过Node
引用进行访问,则会通过Node::bounds
引用与LeafNode::bounds
和NodeLeaf
进行互动。
e.g。
LeafNode leafNode = new LeafNode();
Node node = leafNode;
leafNode.bounds = xxx; // accessing LeafNode::bounds
node.bounds = yyy; // accessing Node::bounds
在您的情况下,我没有看到任何理由在儿童班级中单独bounds
。考虑将Node::bounds
更改为受保护,并在您的子类中使用它。
答案 1 :(得分:0)
在Java中,在子类“shadow”中声明的字段但不覆盖超类中绑定的字段,如方法所做的那样。子类中声明的字段与超类中的字段分开存在;您可以通过super.field
(或((Ancestor) this).field
访问超类的字段以获取更远的超类)。
因此,您看到的两个bounds
实际上是不同的bounds
- 一个来自InternalNode
,另一个来自Node
。据我所知,在您的情况下,最好从bounds
和LeafNode
完全删除InternalNode
声明,只留在Node
类。< / p>