Consider this example, where the point
package declares:
package points;
public class Point {
protected int x, y;
void warp(threePoint.Point3d a) { if (a.z > 0) // compile-time error: cannot access a.z a.delta(this); }
}
and the threePoint
package declares:
package threePoint;
import points.Point;
public class Point3d extends Point {
protected int z;
public void delta(Point p) { p.x += this.x; // compile-time error: cannot access p.x p.y += this.y; // compile-time error: cannot access p.y }
public void delta3d(Point3d q) { q.x += this.x; q.y += this.y; q.z += this.z; }
}
which defines a class Point3d
. A compile-time error occurs in the method delta
here: it cannot access the protected members x
and y
of its parameter p
, because
while Point3d
(the class in which the references to fields x
and y
occur) is a subclass of Point
(the class in which x
and y
are declared), it is not involved in the
implementation of a Point
(the type of the parameter p
). The method delta3d
can access the protected members of its parameter q
, because the class Point3d
is
a subclass of Point
and is involved in the implementation of a Point3d
.
The method delta
could try to cast (§5.4, §15.15) its parameter to be a Point3d
, but this cast would fail, causing an exception, if the class of p
at run time were not Point3d
.
A compile-time error also occurs in the method warp: it cannot access the protected member z
of its parameter a
, because while the class Point
(the class in which the reference to field z
occurs) is involved in the implementation of a Point
(the type of the parameter a), it is not a subclass of Point
(the class in which z
is declared).