无法理解为什么这不是子类代码?

时间:2019-07-23 11:03:01

标签: java inheritance polymorphism

package other;
import animal.*;

public class Calf extends Horse {
    public static void main(String[] args) {
        Calf t = new Calf();
        t.neigh();

        Horse h = new Horse();
        //I find it interesting that following would be a compiler error
        //neigh() has protected access in animal.horse
        //what is then considered subclass code if not that?
        h.neigh();
    }
}

我不明白为什么这段Java代码会引发编译器警告。看评论。 Horse类具有受保护的neigh()方法。 保护应该意味着代码可以在类本身,在同一包中的类中以及在子类中使用。 小牛不在同一包装中。在Horse参考上调用.neigh的代码不起作用。为什么不这样做-我看到它在马的子类中的逻辑,因此.neigh()应该可以访问。或者如果逻辑是这是Horse引用并且neigh()与Horse中的代码有关,那么对于Horse来说,受保护的Horse.neigh()也应该是可访问的。 我想念什么。我能否得到清晰的解释,为什么尽管这段代码(h.neigh())在Horse-s的子类中也无法访问。

3 个答案:

答案 0 :(得分:2)

受保护的访问权限意味着您只能从所有者类或通过扩展所有者类的类访问此成员。第一个例子是好的:

Calf t = new Calf();
t.neigh();

因为您正在通过扩展Horse(所有者)的Calf实例进行访问。 第二个示例中令人困惑的部分是您位于Calf类之内,但实际上您试图通过Horse实例本身直接访问此成员,这违反了受保护的访问规则。 “访问方法”与“调用方法”的想法不同

答案 1 :(得分:2)

我发现an article that explains出现这种晦涩行为的原因(实际上在Java语言规范中已引用):

  

让   米   成为班级中宣布的成员   c   属于包装   p   。如果   米   是   公共的,任何类都可以(在其中编码)访问它。如果   米   是私有的,可以访问   只有通过   C   。如果   米   具有默认访问权限,只能由所属的任何类访问   至   p   。   如果   米   受保护,情况会稍微复杂一些。第一,   米   可以访问   由属于的任何阶层   p   ,就好像它具有默认访问权限一样。另外,可以访问   通过任何子类   s   的   c   属于与   p   ,以及以下内容   限制:如果   米   不是静态的,则该类   Ø   其成员所在的对象的   必须访问   s   或      ,书面   Ø   ≤   s   (如果   米   是静态的,限制   不适用:   米   可以随时被访问   s   )。

     

受保护访问的限制阻止了对受保护访问的几乎任意访问   对象的实例成员。假设   米   是受保护的实例字段   宣告   C   。没有限制,任何阶级   X   可以阅读的内容   领域   米   任何类的对象   C   ,使用以下技巧:定义一个子类   s   的   C   (仅当   C   不是最终的,因此是上面的“几乎”副词);声明一个   方法中   s   需要一个类的对象   C   作为参数并返回的内容   它的   米   领域;并有   X   调用此方法。

答案 2 :(得分:-1)

如果创建对象并尝试访问任何受保护的部件,它将失败-因为通过访问的对象始终仅适用于public。现在,我认为您的疑问是,您在子类中调用了此方法。 -您在这里遗漏了一点。您访问/调用受保护方法的区域位于main()内部。它是静态块,因此不是对象行为。您可以使用super关键字在child的实例方法内部调用您的受保护方法。