Continuing Reading Java Language Specification turned to chapter Classes
Now in section Constructors In Java.
Note it does not always imply that the constructor is accessible whenever the class is accessible.
Can we predict the output of the program?
package classes.ConstructorsExamples.packageA;
public class Outer {
Outer() {
System.out.println("Came Here Outer");
}
protected class Inner {
Inner() {
System.out.println("Came Here Inner");
}
}
}
package classes.ConstructorsExamples.packageB;
import classes.ConstructorsExamples.packageA.Outer;
class SonOfOuter extends Outer {
void foo() {
new Inner(); // compile-time access error
}
}
If the class is declared public, then the default constructor is implicitly given the access modifier public if the class is declared protected, then the default constructor is implicitly given the access modifier protected; if the class is declared private, then the default constructor is implicitly given the access modifier private; otherwise, the default constructor has the default access implied by no access modifier.
The rule that the default constructor of a class has the same access modifier as the class itself is simple and intuitive. Note, however, that this does not imply that the constructor is accessible whenever the class is accessible. Consider
The constructor for Inner is protected. However, the constructor is protected relative to Inner, while Inner is protected relative to Outer. So, Inner is accessible in SonOfOuter, since it is a subclass of Outer. Inner's constructor is not accessible in SonOfOuter, because the class SonOfOuter is not a subclass of Inner! Hence, even though Inner is accessible, its default constructor is not.
Now turned into section "Accessing Members of Inaccessible Classes" which relates more to be above example and also more about package visibility stuff.
Always Note:
Even though a class might not be declared public,instances of the class might be available at run time
to code outside the package in which it is declared by means a public superclass or superinterface.
An instance of the class can be assigned to a variable of such a public type. An invocation of a public method of the object referred to by such a variable may invoke a method of the class if it implements
or overrides a method of the public superclass or superinterface.
(In this situation, the method is necessarily declared public, even though it is declared
in a class that is not public.)
For Example:
package classes.accessability.points;
public class Point {
public int x, y;
public void move(int dx, int dy) {
System.out.println("Point:move");
x += dx; y += dy;
}
}
package classes.accessability.morePoints;
import classes.accessability.points.Point;
public class OnePoint {
public static Point getOne() {
return new Point3d();
}
}
package classes.accessability.morePoints;
class Point3d extends classes.accessability.points.Point {
public int z;
public void move(int dx, int dy, int dz) {
super.move(dx, dy); z += dz;
}
public void move(int dx, int dy) {
System.out.println("Point3D:move");
move(dx, dy, 0);
}
}
package classes.accessability.morePoints;
public class Point4d extends Point3d {
public int w;
public void move(int dx, int dy, int dz, int dw) {
super.move(dx, dy, dz); w += dw;
}
}
package classes.accessability.otherPackage;
import classes.accessability.morePoints.OnePoint;
import classes.accessability.morePoints.Point4d;
public class OtherClass {
public static void main(String[] args) {
OnePoint.getOne().move(23,34);
Point4d point4d=new Point4d();
point4d.move(10,10,90);
point4d.move(10,0);
point4d.move(10,10,10,10);
System.out.println(point4d.z);
}
}
An invocation morePoints.OnePoint.getOne() in yet a third package would return a Point3d that can be used
as a Point, even though the type Point3d is not available outside the package morePoints.
The two argument version of method move could then be invoked for that object, which is permissible because
method move of Point3d is public (as it must be, for any method that overrides a public method must itself
be public, precisely so that situations such as this will work out correctly). The fields x and y of that object could also be accessed from such a third package.
While the field z of class Point3d is public, it is not possible to access this field from code outside the package morePoints, given only a reference to an instance of class Point3d in a variable p of type Point. This is because the expression p.z is not correct, as p has type Point and class Point has no field named z; also, the expression ((Point3d)p).z is not correct, because the class type Point3d cannot be referred to
outside package morePoints.
The declaration of the field z as public is not useless, however. If there were to be, in package morePoints, a public subclass Point4d of the class Point3d:
package morePoints;
public class Point4d extends Point3d {
public int w;
public void move(int dx, int dy, int dz, int dw) {
super.move(dx, dy, dz); w += dw;
}
}
then class Point4d would inherit the field z, which, being public, could then be accessed by code in
packages other than morePoints, through variables and expressions of the public type Point4d.
Hope this explanation helps.
Tuesday, 25 September 2007
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment