从Java中的子类访问受保护的方法时,为什么会出现编译错误?

时间:2014-03-14 17:03:04

标签: java inheritance subclass protected

我正在阅读Java中的protected modifier,哪些字段可以在同一个包和子类中访问。

现在我写了一些代码。

package com;

public class Parent {

    protected void print()
    {
        System.out.println("dFDF");
    }
}

现在是子类。

package abstraact.concept;

import com.Parent;

    public class BaseParent extends Parent{

        public void printNum()
        {
            Parent p = new Parent();
            p.print(); /** Getting error here */
                    // The method print() from the type Parent is not visible
        }



        public static void main(String[] args) {
            BaseParent pp = new BaseParent();
            pp.printNum();

        }
    }

为什么我收到错误? 因为可以从子类访问受保护的方法/变量。

5 个答案:

答案 0 :(得分:7)

这是一个常见的"悖论"在Java,这根本不是悖论。简单地说,由于语言的安全性(可见性)规则,人们无法通过另一个包中的对象引用访问受保护的方法。

声明新对象后,它具有(或允许)的可见性由代码所属的包控制,而不是由继承层次结构控制。

调用

super.print();

this.print();

会奏效。

答案 1 :(得分:4)

仔细尝试并理解陈述。受保护仅在派生类中可见。这对于继承来说是正确的。但是,当您创建父类型的对象时,您不使用继承。这意味着Parent不是在那里派生的,父的功能是受保护的。但是,如果使用super.print(),它将通过继承引用Parent并获取该函数。

所以你的解决方案是替换:

Parent p = new Parent();
p.print();

super.print();

答案 2 :(得分:2)

致电super.print()而不是声明新的Parent对象

答案 3 :(得分:1)

如果包不同,则无法访问受保护的方法。您可以按如下方式访问此方法:

 BaseParent pp = new BaseParent();
 pp.print();

super.print();

答案 4 :(得分:0)

将print方法声明为protected,允许它由子类BaseParent继承。

当BaseParent中的代码引用其自己的(继承)版本的" print"时,这是允许的,因为它已成为该子类的一部分。 但是,子类仍然不能引用父类自己的方法版本(虽然在同一个包中会覆盖它),因为" protected" keyword只允许其他包中的子类继承并使用自己的方法版本。

经过一段时间的努力去理解错误出现的原因后,我就开始考虑这个问题了。

Oracle 6.6.6节http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.2.1中的文档以自己的方式说明了这一点:

  

对象的受保护成员或构造函数可以从包外部访问,只能通过负责实现该对象的代码来声明该对象

因此BaseParent仅负责其自己的继承print methoid,而不是父类中的原始。