为什么另一个包中的子类无法访问受保护的方法?

时间:2013-11-13 08:54:10

标签: java package subclass protected modifier

我在两个不同的包中有两个类:

package package1;

public class Class1 {
    public void tryMePublic() {
    }

    protected void tryMeProtected() {
    }
}


package package2;

import package1.Class1;

public class Class2 extends Class1 {
    doNow() {
        Class1 c = new Class1();
        c.tryMeProtected(); // ERROR: tryMeProtected() has protected access in Class1
        tryMeProtected();  // No error
    }    
}

我理解为什么调用tryMeProtected()时没有错误,因为Class2看到此方法,因为它继承自Class1

但为什么Class2的对象无法使用Class1c.tryMeProtected();的对象上访问此方法?

7 个答案:

答案 0 :(得分:14)

受保护的方法只能通过包之外的子类中的继承来访问。因此第二种方法tryMeProtected();起作用。

下面的代码不会编译,因为我们没有调用protected方法的继承版本。

 Class1 c = new Class1();
 c.tryMeProtected(); // ERROR: tryMeProtected() has protected access in Class1

请按照此stackoverflow链接获取更多解释。

答案 1 :(得分:10)

我相信你误解了packageprotected知名度之间的差异。

package package1;

public class MyClass1 {
    public void tryMePublic() { System.out.println("I'm public"); }
    protected void tryMeProtected() { System.out.println("I'm protected"); }
    void tryMePackage() { System.out.println("I'm package"); }
}
    无论您身在何处,都可以访问
  • tryMePublic
  • 每个子类和同一包中的每个类都可以访问
  • tryMeProtected
  • tryMePackage将在同一个包中的每个类都可访问(如果它们位于不同的包中,则不在子类中提供)

儿童班在同一个包中

package package1;

public class Class2 extends MyClass1 {
    public void doNow() {
        tryMePublic(); // OK
        tryMeProtected(); // OK
        tryMePackage(); // OK
    }    
}

不同包装的儿童班

package package2;

import package1.MyClass1;

public class Class3 extends MyClass1 {
    public void doNow() {
        MyClass1 c = new MyClass1();
        c.tryMeProtected() // ERROR, because only public methods are allowed to be called on class instance, whereever you are
        tryMePublic(); // OK
        tryMeProtected(); // OK
        tryMePackage(); // ERROR
    }    
}

答案 2 :(得分:2)

您使用两个不同的包,并且不通过直接继承访问父属性,而是通过子类中声明的中间父实例(类似于组合)访问。 =>这不是protected的工作方式。

只有直接继承才能覆盖受保护的父级属性。

因此,您可以这样做:

public class Class2 extends Class1 {
    doNow() {
        tryMeProtected();  // No error since direct inheritance 
    }    
}

但从未这样:

public class Class2 extends Class1 {
    doNow() {
        Class1 c = new Class1();
        c.tryMeProtected(); // this is not a direct inheritance! since `c`, although a parent one is an intermediate instance created in the child instance. => bad
    }    
}

事实上,这是protected关键字经常被误解的特殊性。

答案 3 :(得分:1)

根据Java Protected Access修饰符定义在超类中声明受保护的方法只能由其他包中的子类或受保护成员类的包中的任何类访问。

您无法通过创建类的对象来访问受保护的方法。 因此,要访问Protected方法,您必须扩展超类。(这解释了您的第二个调用是正确的)

答案 4 :(得分:0)

可以通过两种方式实现

<强> 1。通过创建Child类的对象然后访问Parent类的受保护方法。

包1

public class Class1 {
    protected void m1() {
        System.out.println("m1 called");
    }
}

包2

public class Class2 extends Class1 {

    public static void main(String[] args) {
        Class2 class2 = new Class2();
        class2.m1();
    }
}

<强> 2。或者直接从Child类

调用该方法

eg tryMeProtected();

答案 5 :(得分:0)

首先,您需要了解两件事:

1)包“ Y”中类“ X”的protected成员函数可以被子类(即扩展它的类)访问(即使子类不在“ Y”中) )。这就是为什么,

tryMeProtected(); // Showed no error because this was called by class 2 that is the subclass.

2)如果包'Y'中的类'X'的protected成员函数在其他包中,则其自身无法访问。

[一个简单的类比:一只鸟将卵留在一个巢1中,然后飞到了一个鸟巢2。从鸟巢2中,它无法访问它在鸟巢1中保留的卵。] 同样,如果一个类在另一个包中,则该类不能访问其成员函数(除非声明了public)。

这就是为什么:

c.tryMeProtected();  // Showed error because this was called by class 1 reference.
                     //  You can also think of it as class 1 cannot inherit itself.

答案 6 :(得分:0)

protected修饰符是1.Package Private 2.可以被其他包的子类看到。 现在,两者之间的主要区别是:

MyClass1 c = new MyClass1();
    c.tryMeProtected();

tryMyProtected(); 

是使用MyClass1引用而不是继承。 MyClass1在不同的程序包中,并且此代码不是从MyClass1继承的。