Search code examples
javaaccess-specifier

Java-Access Speficier


Can someone explain this behaviour?Is it a bug or I am missing something obvious?

1)Create 2 packages, say pack1 and pack2 in same directory.

2)In pack1 create a class X

package pack1;
import pack2.*;
public class X
{
  void eat()
  {
   System.out.println("X eat");
  }

  public static void main(String args[])
  {
   X x = new Y();
   x.eat(); //accessing eat() method on Instance of Y. 
   //But since eat() is not public or protected its visibility  must be limited to class X
   System.out.println("Done");
  }
}

3)Now in pack2 create a class Y

package pack2;
import pack1.*;
public class Y extends X
{
}

The method eat shouldn't be available to class Y as it has 'default' access specifier which limits its visibility to the package it is declared (Package X). So, this method shouldn't be available in class Y. But When I compile and Execute this code, it works fine. Isn't its a violation of 'default' access specifier?

Also If I change X x = new Y() to Y x = new Y(), then compilation fails!!


Solution

  • [EDIT]

    1) The method eat shouldn't be available to class Y as it has 'default' access specifier which limits its visibility to the package it is declared (Package X). So, this method shouldn't be available in class Y.

    Answer: You are not accessing the eat method of Y, you are accessing the eat method of X. Moreover, you are invoking it from main method of X which means it is visible (the call is within package pack1).

    Move the code:

    public static void main(String args[])
    {
         X x = new Y();
         x.eat();
         System.out.println("Done");
    }
    

    from class X (in pack1) to class Y (in pack2) to see that eat() is no longer accessible. You will receive the compiler error message

    The method eat() from the type X is not visible

    2) Also If I change X x = new Y() to Y x = new Y(), then compilation fails!!

    Answer: Because, like before, the method you are accessing is not in class Y but class X. As the eat() method has the default access modifier, it is not available via inheritance. So, as the variable is now of type Y (not X), you can no longer access this method.