0

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!!

Akash Mahajan
  • 512
  • 4
  • 16
  • In the duplicate, replace `private` by `package private` for the answer. The accessibility is determined based on the static type of the expression the method is invoked on. In your case, `X`, not `Y`. – Sotirios Delimanolis Jun 08 '15 at 21:04

1 Answers1

1

[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.

JamesB
  • 7,774
  • 2
  • 22
  • 21
  • Still can't understand. Is it true that the type of reference determines if a method is accessible or not? Is't that weird? A member is accessible or not should be determined by Instance and not by reference. – Akash Mahajan Jun 08 '15 at 21:13
  • What I am saying (perhaps not clearly enough) is to show that the default access is working as expected, move the call to eat to pack2. The call is allowed in the original code because it is being made from within pack1. – JamesB Jun 08 '15 at 21:24
  • @SotiriosDelimanolis Updated my answer. – JamesB Jun 09 '15 at 07:55