为什么在Java中我不能从另一个包中的继承类调用受保护的方法?

8

假设有以下基类:

package bg.svetlin.ui.controls;

public abstract class Control {
    protected int getHeight() {
        //..
    }
    //...
}

同时,在同一个包中,有一个继承了该类的类:

package bg.svetlin.ui.controls;

public abstract class LayoutControl extends Control {
    public abstract void addControl(Control control);
    //...
}

然后,还有另一个包中的第三个类:
package bg.svetlin.ui.controls.screen;

public abstract class Screen extends LayoutControl {
    //...
}

最后,还有实现类,它位于不同的包中:

package bg.svetlin.ui.controls.screen.list;    

public class List extends Screen {

    private final Vector controls = new Vector();

    public void addControl(Control control) {
        height += control.getHeight();
        controls.addElement(control);
    }
}

尽管List继承自Control,而且getHeight()protected的,但出现了以下错误:

getHeight()在bg.svetlin.ui.controls.Control中具有受保护的访问权限。

我已经检查过我的导入是否正确。我正在使用NetBeans。
你有什么想法吗?我认为protected字段和方法对于子类即使在不同的包中也是可见的。
谢谢!

1
在你的抽象类中,方法是 getWidth(),而在子类中你使用了 getHeight()。这只是因为这是示例代码吗? - Ash
是的。谢谢你发现了这个问题。 - Albus Dumbledore
2个回答

19
我认为受保护的字段和方法即使在不同的包中,子类也可以看到。
没错。这个类本身可以访问继承的受保护成员。但是,你试图在某个控制引用上调用 getHeight 方法。你只能在this实例上调用它!
为了更好地理解,让我引用Kathy Sierra的SCJP Preparation Guide:
“但是,对于一个位于包外的子类来说,有权访问超类(父类)成员意味着什么?它意味着子类继承了该成员。然而,这并不意味着子类可以使用超类实例的引用访问该成员。换句话说,protected = inheritance. 子类只能通过继承看到受保护的成员。”

我该如何使一个方法只对类及其子类可用呢?谢谢! - Albus Dumbledore
就像我说的一样,它对你的子类是可用的。但是你只能在此引用上调用它,例如 this.getHeight()(当然,this 是可选的)。不过,将访问器方法设为 public 是一种常见做法。 - jFrenetic
尺寸和位置将由我的库自动保留,因此我想将它们保留为库的私有属性。看来我将不得不将它们设为公共属性了。谢谢! - Albus Dumbledore

2

你说得没错。任何一个子类可以访问受保护的成员或方法,但在addControl方法中你想要访问参数实例的受保护方法。你只能访问List类的受保护方法(this.getHeight())。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接