Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: calling a super class' protected method from a subclass - not visible?

I am calling a super class' protected method from a subclass. Why is this method "not visible"?

I've been reading some posts such as this one, that seem to contradict the following:

Super class:

package com.first;

public class Base
{
    protected void sayHello()
    {
        System.out.println("hi!");
    }
}

Subclass:

package com.second;

import com.first.Base;

public class BaseChild extends Base
{
    Base base = new Base();

    @Override
    protected void sayHello()
    {
        super.sayHello(); //OK :)
        base.sayHello(); //Hmmm... "The method sayHello() from the type Base is not visible" ?!?
    }   
}
like image 936
rapt Avatar asked Mar 24 '16 01:03

rapt


People also ask

Can protected methods be accessed by subclass?

Yes, the protected method of a superclass can be overridden by a subclass.

What happens when a subclass inherits the protected super class?

A subclass inherits all of the public and protected members of its parent, no matter what package the subclass is in. If the subclass is in the same package as its parent, it also inherits the package-private members of the parent.

Can we call protected method from outside class Java?

The protected access modifier is accessible within the package. However, it can also accessible outside the package but through inheritance only. We can't assign protected to outer class and interface. If you make any constructor protected, you cannot create the instance of that class from outside the package.

Can subclass access protected fields superclass Java?

The protected modifier allows a subclass to access the superclass members directly. But the access should be made inside the subclass or from the same package.


2 Answers

base is a variable that is not special in any way: it's not part of a class hierarchy and protected access is not available through it. Even though sayHello has access to protected members of Base, it has that access only through inheritance (since it's not in the same package: the protected keyword allows access via both inheritance and package, see the table in this Oracle tutorial).

Access through this and super is allowed because those are part of the inheritance hierarchy.

like image 184
Paul Hicks Avatar answered Nov 14 '22 21:11

Paul Hicks


This is the correct behavior. In fact, Java Language Specification, section , 6.6.2-1, has an example very similar to yours, with a comment that it should not compile.

The specifics of accessing protected members are detailed in section 6.6.2.1:

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.

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.

It's the last paragraph that describes why the access should be denied. In your example, C is Base, S is BaseChild, and E, the type of variable base, is also Base. Since Base is neither a BaseChild nor a subclass of BaseChild, the access is denied.

like image 25
Sergey Kalinichenko Avatar answered Nov 14 '22 21:11

Sergey Kalinichenko