15
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?

SMUsamaShah
  • 7,677
  • 22
  • 88
  • 131
abson
  • 9,148
  • 17
  • 50
  • 69

9 Answers9

16

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 ;)

Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
  • Derived is a subclass of Base here. – abson Apr 06 '11 at 07:09
  • @abson - hold on, understood your question, was still editing and trying to explain ;) – Andreas Dolk Apr 06 '11 at 07:14
  • I find the logic broken as for why in case of a base class with package-private access, it can offer protected method-level access to its children even when they are in different packages. Don't understand why the class should not be marked as protected as well in this case (as with abstract where min 1 abstract method forces the class to be marked abstract), or at least public to avoid confusion. General rule is class-level access first, followed by member level access. – html_programmer Oct 11 '19 at 10:30
3

Protected access has some special rules that are detailed in the Java Language Specification:

A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.

Jörn Horstmann
  • 33,639
  • 11
  • 75
  • 118
3

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

Christopher Schultz
  • 20,221
  • 9
  • 60
  • 77
irreputable
  • 44,725
  • 9
  • 65
  • 93
2

First think is that you can use protected Object in any ware, but only Different package non-subclass cant access protected member from other class. it means you cant use it directly. first you get that obj and then use.

    package Demos;

    public class AB
    {
        public    int a = 14;
        protected int b = 13;   
    }

and we have another class like

package Example;

import Demos.AB;

public class Ex1 extends AB
{
    public static void main(String[] args)
    {
        AB obj = new AB();          // obj of AB                OR
                                    // AB obj = new Ex1(); object of Ex1 but referance of AB
                                    // cant use protacted member

        System.out.println(obj.a);
        System.out.println(obj.b);  //You can't use 


        Ex1 obj1 = new Ex1();       // you have to make obj of sub-class referance of Ex1
        System.out.println(obj1.a);
        System.out.println(obj1.b);  // Now You can use
    }
}

in this matter you have to extends class of protected member and then use you cant use is directly.

Bhola
  • 392
  • 1
  • 15
1
new Base().display();

It creates a Base object, and then trys to call the display() on it.
Obviously it won't work, because the display() on Base is protected.

RollingBoy
  • 2,767
  • 1
  • 14
  • 8
  • but i am calling it from a class which extends it so it should work fine isn't it? – abson Apr 06 '11 at 07:15
  • @abson: super.display() is fine. But in the example, it creates a new object, then calls through it. Thus it is not going to work, unless they're in the same package. – RollingBoy Apr 06 '11 at 07:22
0

A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.

Pradeep
  • 12,309
  • 3
  • 20
  • 25
0

This is the intended behaviour. protected means that the inherited classes and same package classes can see the method. So, it's what you see.

Vladimir Ivanov
  • 42,730
  • 18
  • 77
  • 103
0

This might be a direct answer to your question, but i see no reason why you would call new Base().display();. Perhaps what you mean in super.display();.

In this case, you are actually using the inherited method, but just because you're inheriting a class, it doesn't mean that you access to the class protected methods (which by definition are only visible to super classes).

The difference is on one case (your example) you're trying to access a protected method from an instance of a class that you inherited. In my example, you can access the protected method through inheritance.

In summary: you can access the method through inheritance context.

Why?

It gives programmers flexibility in deciding which features can only be used or extended by direct descendants.

Sinker
  • 576
  • 1
  • 7
  • 21
-1

display is not a static method inside Base. So, you have to first create an instance of Base and then call display.

Base base = new Base();
base.display();
Piyush Mattoo
  • 15,454
  • 6
  • 47
  • 56