Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protected member access from different packages in java - a curiosity [duplicate]

Tags:

java

protected

package packageOne;
public class Base
{
    protected void display(){
        System.out.println("in Base");
    }
}


package packageTwo;
public class Derived extends packageOne.Base {
    public void show(){
        new Base().display(); //this is not working throws compilation error that display() from the type Base is not visible
        new Derived().display(); //is working
        display(); //is working
    }
}

The two packages are in two different files. But why this behaviour?

like image 571
abson Avatar asked Apr 06 '11 07:04

abson


People also ask

How can a protected member of a class be accessed by its subclass in different package?

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.

How can protected members be accessed in Java?

The protected members are inherited by the child classes and can access them as its own members. But we can't access these members using the reference of the parent class. We can access protected members only by using child class reference.

How do I access protected variables in different packages?

Protected Access Modifier - Protected Variables, methods, and constructors, 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. The protected access modifier cannot be applied to class and interfaces.

How can a protected member be accessed?

Protected members in a class are similar to private members as they cannot be accessed from outside the class. But they can be accessed by derived classes or child classes while private members cannot.


2 Answers

protected allows access from subclasses and from other classes in the same package. That's why any Derived class instance can access the protected method in Base.

The other line creates a Base instance (not a Derived instance!!). And access to protected methods of that instance is only allowed from objects of the same package.


display();

-> allowed, because the caller, an instance of Derived has access to protected members and fields of its subclasses, even if they're in different packages

new Derived().display();

-> allowed, because you call the method on an instance of Derived and that instance has access to the protected methods of its subclasses

new Base().display();

-> not allowed because the caller's (the this instance) class is not defined in the same package like the Base class, so this can't access the protected method. And it doesn't matter - as we see - that the current subclasses a class from that package. That backdoor is closed ;)

like image 134
Andreas Dolk Avatar answered Sep 22 '22 14:09

Andreas Dolk


http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.6

class C
    protected member;

// in a different package

class S extends C 

    obj.member; // only allowed if type of obj is S or subclass of S

The motivation is probably as following. If obj is an S, class S has sufficient knowlege of its internals, it has the right to manipulate its members, and it can do this safely.

If obj is not an S, it's probably another subclass S2 of C, which S has no idea of. S2 may have not even been born when S is written. For S to manipulate S2's protected internals is quite dangerous. If this is allowed, from S2's point of view, it doesn't know who will tamper with its protected internals and how, this makes S2 job very hard to reason about its own state.

Now if obj is D, and D extends S, is it dangerous for S to access obj.member? Not really. How S uses member is a shared knowlege of S and all its subclasses, including D. S as the superclass has the right to define behaviors, and D as the subclass has the obligation to accept and conform.

For easier understanding, the rule should really be simplified to require obj's (static) type to be exactly S. After all, it's very unusual and inappropriate for subclass D to appear in S. And even if it happens, that the static type of obj is D, our simplified rule can deal with it easily by upcasting: ((S)obj).member

like image 37
irreputable Avatar answered Sep 25 '22 14:09

irreputable