Why is the protected method inaccessible from a subclass?

Consider the following code snippets:

package vehicle; public abstract class AbstractVehicle { protected int speedFactor() { return 5; } } package car; import vehicle.AbstractVehicle; public class SedanCar extends AbstractVehicle { public static void main(String[] args) { SedanCar sedan = new SedanCar(); sedan .speedFactor(); AbstractVehicle vehicle = new SedanCar(); // vehicle //WON'T compile // .speedFactor(); } } 

SedanCar is a subclass of AbstractVehicle that contains the protected speedFactor method. I can call the speedFactor method if it is referenced by the same class. When a superclass is used for reference, the speedFactor method speedFactor not available.

What is the reason for hiding the method?

+6
source share
5 answers

Your SedanCar class is in a different package than the AbstractVehicle class. protected can only be obtained from the same package or from subclasses.

In the case of SedanCar :

 SedanCar sedan = new SedanCar(); sedan.speedFactor(); 

You call the protected method from one package: OK. SedanCar is in the car package and the main() method is in the class that is in the car package (actually the same class).

In the case of AbstractVehicle :

 AbstractVehicle vehicle = new SedanCar(); vehicle.speedFactor(); 

You are trying to call the protected method, but from another package: NOT OK. The main() method from which you are trying to call it is in the car package, and AbstractVehicle is in the vehicle package.

Understand this basically:

You have a variable of type AbstractVehicle , which is declared in another package ( vehicle ). It may or may not contain the dynamic type SedanCar . In your case, this is true, but it may also contain an instance of any other subclass defined in another package, for example. in a sportcar . And since you are in the car package ( main() method), you are not allowed to call vehicle.speedFactor() (which is protected by AbstractVehicle.speedFactor() ).

+4
source

Because protected displayed to the class itself (for example, private) and its subclass instances. This is not public.

For instance,

 package vehicles; public abstract class AbstractVehicle { protected int speedFactor() { return 5; } public int getSpeed() { return 10*speedFactor(); //accessing speedFactor() "privately" } } package vehicles.cars; public class SedanCar extends AbstractVehicle { @Override protected int speedFactor() { //overriding protected method (just to show that you can do that) return 10; } @Override public int getSpeed() { return 20*speedFactor(); //this is part of the instance (!!!) therefore it can access speedFactor() protected method too } } package vehicles.main; public class Main { public static void main(String[] args) { AbstractVehicle vehicle = new SedanCar(); int speed = vehicle.getSpeed(); //accessing public method vehicle.speedFactor(); //cannot access protected method from outside class (in another package) } } 

The static main() method is not part of the instance, so it cannot access the protected method.

+4
source

A protected modifier indicates that access to an element can only be accessed in its own package (as is the case with the private package) and, in addition, by subclassing its class in another package.

This is why you cannot directly call a method inside the main method of a vehicle object.

See: https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

+2
source

In my SCJP for Java 1.5 days, one thing I remember was careful with the superclass reference variables. It is not surprising to see this now, and one thing why it is confusing is that this rule is protected, apparently for a subclass or the same package. What if it is a subclass and another package?

If you create another package and execute

 package yetAnotherPackage; import car.SedanCar; public class Main { public static void main(String[] args) { new SedanCar().speedFactor(); } } 

you will see that

 The method speedFactor() from the type AbstractVehicle is not visible 

It seems that the rule is just spreading. As long as you have a subclass and try to access the protected method in the subclass package (or if there is no subclass and then the parent package), you should be good.

0
source

Subclasses in different packages cannot access protected methods and protected variables from the superclass using the superclass link. Only the way to access protected superclass data in a subclass is through inheritance

below are two code snippets

 package nee; import parentdata.Parent; class Child extends Parent{ public void testIt(){ System.out.println(x); // able to access protected x defined in Parent } } package nee; import parentdata.Parent; class Child extends Parent { public void testIt(){ Parent p=new Parent(); System.out.println(px) // results in compile time error } } 

In the language specification 6.6.2.1 Access to a protected member

Let C be the class in which the protected member m is declared. Access is permitted only inside the body of the subclass S of C. In addition, if Id denotes an instance field or instance method, then:

 If the access is by a qualified name Q.Id, where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S. If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S. 

for more details visit http://www.jot.fm/issues/issue_2005_10/article3.pdf

0
source

Source: https://habr.com/ru/post/988299/


All Articles