Why subclass in another package cannot access a protected method?

房东的猫 提交于 2019-12-17 10:51:33

问题


I have two classes in two different packages:

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
    }    
}

I can understand why there is no error in calling tryMeProtected() since Class2 sees this method as it inherits from Class1.

But why isn't it possible for an object of Class2 to access this method on an object of Class1 using c.tryMeProtected(); ?


回答1:


Protected methods can only be accessible through inheritance in subclasses outside the package. And hence the second approach tryMeProtected(); works.

The code below wont compile because we are not calling the inherited version of protected method.

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

Follow this stackoverflow link for more explaination.




回答2:


I believe you misunderstand the difference between package and protected visibility.

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 will be accessible wherever you are.
  • tryMeProtected will be accessible to every subclass AND every class in the same package.
  • tryMePackage will be accessible to every class in the same package (not available in children class if they are in a different package)

Children class in the same package

package package1;

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

Children class in different package

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
    }    
}



回答3:


You use two different packages and you don't access your parent attributes by direct inheritance, but by an intermediate parent instance declared in the child class (similar to composition). => that's the not the way protected works.

Only direct inheritance allows protected parent's attributes to be reach.

Thus, you can do this:

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

but never this:

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
    }    
}

Indeed, this is a particularity of protectedkeyword often misunderstood.




回答4:


As per Java Protected Access modifier definition methods which are declared protected in a superclass can be accessed only by the subclasses in other package or any class within the package of the protected members' class.

you can't access protected method by creating object of class. So for accessing Protected method you have to extend the superclass.(this explains your 2nd call is correct)




回答5:


It can be acheived by two ways

1. Either by making an object of Child class and then accessing the protected method of Parent class.

PACKAGE 1

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

PACKAGE2

public class Class2 extends Class1 {

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

2. Or by directly calling the method from the Child class

eg tryMeProtected();




回答6:


First of all, you need to understand two things:

1) The protected member functions of a class 'X' in package 'Y' can be accessed by the subclass i.e. a class that extends it (even if the subclass is in the package other than 'Y'). That is why,

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

2) A protected member function of a class 'X' in package 'Y' cannot be accessed by itself if it is in other packages.

[ A simple analogy: A bird that has its eggs kept in a nest 1 has flown to a nest 2. From the nest 2, it cannot access its egg kept in nest 1.] Similarly, a class cannot access its member function (unless public declared.) if it is in the other package.

That is why :

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


来源:https://stackoverflow.com/questions/19949327/why-subclass-in-another-package-cannot-access-a-protected-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!