views:

235

answers:

6

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.

+3  A: 

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.

pajton
protected modifier allows access in inherited classes *directly* because after inheritance because they become members of the subclass. We are not allowed to access them through an object of the superclass, right?
PuneCoder
@PuneCoder We are not allowed to access them from outside the package _and_ the subclass hierarchy.
Péter Török
+2  A: 

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.

Péter Török
A: 

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

Jens Schauder
+1  A: 

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

Michael Pilat
yeah, dat's right. i think that what i have said, the thought just got jumbled. i think i have to put a parenthesis somewhere... :)
ultrajohn
A: 

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!

ultrajohn
A: 

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.

calvinkrishy