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();
?
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.
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
}
}
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 protected
keyword often misunderstood.
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)
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();
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