Reputation: 21
I have the following two files:
Fruit.java:
package superClass;
public class Fruit {
protected static void printName() {
System.out.println("My name is Khan");
}
}
Apple.java:
package food;
import superClass.*;
public class Apple {
public static void main(String[] args) {
int i, j;
for(i = 0; i < 5; i++) {
for(j = 0; j < i; j++) {
System.out.print("*");
}
System.out.println();
}
printName(); // Call inherited member - NO ERROR, expected
Fruit f = new Fruit();
f.printName(); // Call instantiated member - ERROR, expected
}
}
As expected, I do not have access to the protected method printName from the class Apple as they reside in different packages. I get the following error:
printName() has protected access in superClass.Fruit
Perfectly correct. But if I inherit from the class superClass as follows I do not get any error!
package food;
import superClass.*;
public class Apple extends Fruit {
public static void main(String[] args) {
int i, j;
for(i = 0; i < 5; i++) {
for(j = 0; j < i; j++) {
System.out.print("*");
}
System.out.println();
}
printName(); // Call inherited member - NO ERROR, expected
Fruit f = new Fruit();
f.printName(); // Call instantiated member - NO ERROR, WHAT????
}
}
Why is it allowing me to access the protected member of another class in a different package by reference? This is supposed to be an illegal access, is it not?
I am confused! Someone please help.
The code was compiled using Java 1.6.0_18.
Upvotes: 2
Views: 4780
Reputation: 187
The protected members of the superclass are accessible from the subclass, even if the superclass is in another package but we can use by reference of that class in which protected member is used because at this time that class is owner of protected member. Suppose protected member in
com.pack1 class A { protected int i;}
com.pack2 class D { System.out.println(i); System.out.println(a1.i); }
i
is perfect but a1.i
is not perfect, give error.
In class D we can use protected member by reference of d not reference of class A
Upvotes: 3
Reputation: 122
Here is the thing, when you said
printName(); // Call inherited member - NO ERROR, expected
Fruit f = new Fruit();
f.printName(); // Call instantiated member - NO ERROR, WHAT????
keep in mind that printName is a static method, so even if the compiler accepts the form
f.printName();
The real form will always be
Fruit.printName(); // protected accesor allows the use of the method
Apple.printName(); // or just
printName(); // at the end everything is the same to this call
So at the end you get the static method inherited, you are just confused about how static methods works, they are class methods not instance, even if the compiler does not complain about writing the form
f.printName();
The real thing happening inside is class access. But is sure the compiler gives a warning similar to this:
The static method printName() from the type Fruit should be accessed in a static way
Upvotes: 1
Reputation: 3928
The behavior you observe is because of the fact that printName is static. The protected modifier provides visibility of that method in the sub-class but if the method is non-static, invocation of that method is possible only through the instance of a sub-class (the concern you were raising "if I inherit from the class superClass as follows I do not get any error!"). The JLS section 6.6.2.1 defines this succinctly.
Upvotes: 4
Reputation: 2597
Aye, dat's good that you did not get any error... that could have been a violation in the Java language specification or a bug... Anyway, that's right. that's the definition of protected access modifier. Protected is a like an intermediate level of class members' accessibility from the outside or from other classes. that's between private and public i suppose. protected class members are accessible ( from subclasses of a class ) and (from other classes as long as they belong to the same package). just a thought!
Upvotes: 0
Reputation: 116266
This is the definition of protected
access: protected
members are accessible from subclasses, regardless of being in a different package.
Here is a reference to the access modifiers of Java.
Note: in Java, the convention is to have lowercase package names, i.e. superClass
is not adhering to this convention. You might be bitten by this - especially if you are developing on *nix platforms where file and directory names are case sensitive.
Upvotes: 3
Reputation: 6520
The protected
members of the superclass are accessible from the subclass, even if the superclass is in another package. See the second part of this page and accompanying table/diagram:
http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html
Upvotes: 1
Reputation: 81907
Are you confusing protected with the default (aka package) modifier? The later restricts access to members of the same package.
Protected restricts access to members of the package and classes inheriting from the class in question.
See http://java.sun.com/docs/books/jls/second_edition/html/names.doc.html#62587 for details
Upvotes: 0
Reputation: 16226
protected modifier allows access in inherited classes. If you need to restrict access to classes only in certain package you need a "package" modifier, which is just an empty modifier, i.e. write method like this:
static void printName()
and it will have the package visibility.
Upvotes: 3