Suppose "class A2" and p"ublic class A" are in the A.java file, and class B is in a different package than A.java.
This is Class B
public class B {
protected void protectedMethod() {
}
}
And below is A.java File
class A2 extends B {
void tFunc() {
protectedMethod();
}
public class A extends A2 {
void tFunc1() {
protectedMethod(); // OK
A2 a2 = new A2();
a2.protectedMethod(); // Compile Error
why can a2.protectedMethod()
not compile??
I understand protected can be called if it is an inheritance relationship, but why does a compilation error occur when A inherits A2 and A2 inherits B?
CodePudding user response:
Because the language spec says so. See 6.6.2.1. Access to a protected Member
Let C be the class in which a protected member is declared. Access is permitted only within the body of a subclass S of C.
A subclass S is regarded as being responsible for the implementation of objects of class C. Depending on C's accessibility, S may be declared in the same package as C, or in different package of the same module as C, or in a package of a different module entirely.
In addition, access to an instance field or instance method is permitted based on the form of the qualified name, field access expression (§15.11), method invocation expression (§15.12), or method reference expression (§15.13):
If the access is by (i) a qualified name of the form ExpressionName.Id or TypeName.Id, or (ii) a field access expression of the form Primary.Id, then access to the instance field Id is permitted if and only if the qualifying type is S or a subclass of S.
The qualifying type is the type of the ExpressionName or Primary, or the type denoted by TypeName.
See also: The True Meaning of private and protected if you find standardese hard to read:
Inside a package, the true meaning of the protected keyword is quite simple. To classes in the same package, protected access looks just like package access. Any class can access any protected member of another class declared in the same package.
When you have subclasses in other packages, however, the true meaning of protected becomes more complex. Take a look at the inheritance hierarchy shown in Figure 5-5. In this hierarchy, class Cup, which is declared in the com.artima.vcafe.dishes package, declares a protected instance method named getSize(). This method is accessible to any subclasses declared anywhere, including those shown declared in package com.artima.other. Any objects whose class descends from Cup--instances of class CoffeeCup, CoffeeMug, EspressoCup, or TeaCup-- can invoke getSize() on themselves. Whether they can invoke getSize() on a reference to another object, however, depends upon where that other object sits in the inheritance hierarchy.
package A; public class Cup {} package B; public class TeaCup extends Cup {} public class CoffeeCup extends Cup {} public class CoffeeMug extends CoffeeCup {} public class EspressoCup extends CoffeeCup {}
If a protected instance variable or instance method is accessible to a class, that class can access the protected member through a reference only if the reference type is the class or one of its subclasses. For example, for code in the CoffeeCup class to invoke getSize() on a reference to another object, that reference must be of type CoffeeCup or one of its subclasses. A CoffeeCup object could therefore invoke getSize() on a CoffeeCup reference, a CoffeeMug reference, or an EspressoCup reference. A CoffeeCup object could not, however, invoke getSize() on a Cup reference or a TeaCup reference.
If class has a protected variable or method that is static, the rules are different. Take as an example the protected static method getCupsInUse() declared in class Cup as shown in Figure 5-5. Any code in a subclass of Cup can access a getCupsInUse() by invoking it on itself or invoking it on a reference of type Cup or any of its subclasses. Code in the EspressoCup class could invoke getCupsInUse() on itself or on a reference of type Cup, CoffeeCup, CoffeeMug, EspressoCup, or TeaCup.
CodePudding user response:
Protected method can be used in context Class A by writing
super.protectedMethod()
Creating new instance of A2 in A class breaches the rule that protected methods cannot be accessed from different packages.