Link to home
Start Free TrialLog in
Avatar of perfect_tranquility
perfect_tranquilityFlag for United States of America

asked on

Java Access Specifier Issue

I made 2 packages and 3 classes,one being the superclass of the other, third is the class used to test

package p1 has class d and c
package p2 has class class1
Here is the complete code as typed in Eclipse IDE:

package p1;
public class d {
protected void f(){System.out.println("F() COMING FROM SUPERCLASS D");}
}

package p2;
import p1.d;
public class c extends d{}

package p1;
import p2.c;
public class class1
{
static c cc=new c();
public static void main(String[] args) {
cc.f(); /* target line */
}      
}

question: why does the line marked as target line execute fine? I think the f() coming all the way from class d still has protected access in class c, so how come it was executed by an instance of class c in class class1. To me, public access is needed for that.
Thanks
R
Avatar of gnoon
gnoon
Flag of Thailand image

No, protected access is allowed in the same class (and subclasses in any package). Different from default access of a method or variable, which allows in the same class (and subclasses in the same package)

Did you try the default access

package p1;
public class d {
void f(){System.out.println("F() COMING FROM SUPERCLASS D");}
}
Avatar of Mick Barry
it can access it because class1 and d are in the same package
Avatar of perfect_tranquility

ASKER

ok, classes class1 and d are in the same package. however that function f() is being accessed through an object and reference variable of type c which is not in the same package.

The class c is not in the same package and this class inherits the function f() from d. the static variable cc can not directly access it from class d, it can only do so from class c. if this is so, why does it still matter that those two classes are in same package.

Sorry but I am confused.

R
f() is a function of c, and so is accessible by other classes in the same package as d.
The fact that it is inherited is irrelevant (otherwise you could just subclass a class to change the access permissions of inherited methods)
Here the spec

Modifier      Class   Package     Subclass    World
=================================================
public          Y        Y                  Y                Y
protected    Y        Y                  Y               N
no modifier  Y        Y                 N               N
private        Y        N                 N               N

If you modify d to default access specifier

package p1;
public class d {
void f(){System.out.println("F() COMING FROM SUPERCLASS D");}
}

and compile it. Afterward, you can compile class c successfully since it's not call to f(), and now no f() in c because it's protected by different package.
If you're trying to compile class1, you will get compile error because it extends c and no f() in c.
really sorry ... typos ;-)

Afterward, you can compile class d successfully since it's not call to f(), and now no f() in d because it's protected by different package.
If you're trying to compile class1, you will get compile error because it extends d and no f() in d.

It also make me confused
Oh! It's already on the right.

Maybe I was sleepless last night. I need a pretty nurse and shall leave from this topic now.
Sorry guys.
objects :f() is a function of c, and so is accessible by other classes in the same package as d.
The fact that it is inherited is irrelevant (otherwise you could just subclass a class to change the access permissions of inherited methods

It is not a function of c. It is declared in d and that makes it accessible to other classes in the parent package of class d. I know we do not even need protected specifier for that to be true. The default package access works fine there.
gnoon:Did you try the default access

gnoon, the default access would not work in this case. try that on computer and let me know if you find otherwise
> It is not a function of c.

sorry, that was a typo

> It is declared in d and that makes it accessible to other classes in the parent package of class d.

thats right, and thats why class1 can access it.

objects: it can access it because class1 and d are in the same package
if that were the only reason then we would not have to use the protected specifier. remove that and then the code does not work.
anyway, too much time has gone by already.

R
> It is declared in d and that makes it accessible to other classes in the parent package of class d.

objects:thats right, and thats why class1 can access it.

OK, but  there are various ways how a class can "access" a function from another class. in this case, I used an instance of class c. remember this instance is trying to access the funtion from class c not d directly which is in a different package. then how come it runs?
Answering this question is the key to the solution
> remove that and then the code does not work.

correct because then it would not inherit the method
trying to override the function coming from class d  stops the code from running.

public class c extends d {
      protected void f(){System.out.println("F IN CLASS C");}
}
ASKER CERTIFIED SOLUTION
Avatar of Mick Barry
Mick Barry
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial