1

I have the following two class in two different packages. my access modifier for instance method is protected which means any subclass in same or different package has access to it right?. however, in Eclipse I see the following message on my subclass Cat on line 17

The method testInstanceMethod() from the type Animal is not visible 

My code for super and subclass are below.

package inheritance;

public class Animal {

    public static void testClassMethod() {
        System.out.println("The class" + " method in Animal.");
    }
    protected void testInstanceMethod() {
        System.out.println("The instance " + " method in Animal.");
    }
}

package testpackage;

import inheritance.Animal;

public class Cat extends Animal{
        public static void testClassMethod() {
            System.out.println("The class method" + " in Cat.");
        }
        public void testInstanceMethod() {
            System.out.println("The instance method" + " in Cat.");
        }

        public static void main(String[] args) {
            Cat myCat = new Cat();
            Animal myAnimal = myCat;
            myAnimal.testClassMethod();
            myAnimal.testInstanceMethod();
        }
    }
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
brain storm
  • 30,124
  • 69
  • 225
  • 393
  • The scope of the access modifiers are clearly visualized in [this table](http://stackoverflow.com/a/33627846/276052). The problem in this case is that you tried to call `testInstanceMethod` on an `Animal`. Suppose you would have named the method `meow()` (it would make sense to have such method in a class called `Cat`). Now it's pretty clear that it wouldn't make sense to let you call `meow()` on any `Animal`. The `Animal` could have been a `Dog`! :-) – aioobe Nov 13 '15 at 13:13

1 Answers1

3

The protected access modifier does not grant package access meaning classes within the same package are not granted access to protected fields.

Protected does grants access to classes derived from the base class (inheritance relationship) containing the field and that are in the same package.

So to satisfy protected level access two conditions must be met:

  1. The classes must be in the same package.
  2. There must be an inheritance relationship.

In your example only one of these conditions is satisfied (there is an inheritance relationship between the classes), however they are not in the same package.

If you moved Animal into the same package as Cat the code would compile.

package testpackage;

public class Animal {

    public static void testClassMethod() {
        System.out.println("The class" + " method in Animal.");
    }
    protected void testInstanceMethod() {
        System.out.println("The instance " + " method in Animal.");
    }
}
Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
  • 1
    I found in the accepted answer here that "Inline Link - http://stackoverflow.com/questions/5416074/isnt-package-private-member-access-synonymous-with-the-default-no-modifier" that protected grants access to subclasses in different packages, in which case why the above code throws error? – brain storm Aug 28 '13 at 17:42
  • I find this answer a bit confusing. The protected modifier *does* grant access within the package. See [this table](http://stackoverflow.com/a/33627846/276052) for a clear visualization. The problem here (afaict) is that the static type of `myAnimal` is `Animal` which does not expose the `testInstanceMethod`. (The code *does* compiles if you change the static type of `myAnimal` to `Cat`, even without putting them in the same package.) – aioobe Nov 13 '15 at 13:10