CHAPTER 8: Class Declarations Previous
Previous
Java Language
Java Language
Index
Index
Next
Next

8.2 Class Members

8.2.1 Examples of Inheritance

The members of a class type are all of the following:

Members of a class that are declared private are not inherited by subclasses of that class. Only members of a class that are declared protected or public are inherited by subclasses declared in a package other than the one in which the class is declared.

Constructors and static initializers are not members and therefore are not inherited.

The example:


class Point {
	int x, y;
	private Point() { reset(); }
	Point(int x, int y) { this.x = x; this.y = y; }
	private void reset() { this.x = 0; this.y = 0; }
}


class ColoredPoint extends Point {
	int color;
	void clear() { reset(); }														// error
}


class Test {
	public static void main(String[] args) {
		ColoredPoint c = new ColoredPoint(0, 0);													// error
		c.reset();													// error
	}
}

causes four compile-time errors:

which invokes the constructor, with no arguments, for the direct superclass of the class ColoredPoint . The error is that the constructor for Point that takes no arguments is private , and therefore is not accessible outside the class Point , even through a superclass constructor invocation (S8.6.5).


8.2.1 Examples of Inheritance

This section illustrates inheritance of class members through several examples.

8.2.1.1 Example: Inheritance with Default Access

Consider the example where the points package declares two compilation units:


package points;



public class Point {
	int x, y;

	public void move(int dx, int dy) { x += dx; y += dy; }
}

and:


package points;



public class Point3d extends Point {
	int z;
	public void move(int dx, int dy, int dz) {
		x += dx; y += dy; z += dz;
	}
}

and a third compilation unit, in another package, is:


import points.Point3d;



class Point4d extends Point3d {
	int w;
	public void move(int dx, int dy, int dz, int dw) {
		x += dx; y += dy; z += dz; w += dw; // compile-time errors
	}
}

Here both classes in the points package compile. The class Point3d inherits the fields x and y of class Point , because it is in the same package as Point . The class Point4d , which is in a different package, does not inherit the fields x and y of class Point or the field z of class Point3d , and so fails to compile.

A better way to write the third compilation unit would be:


import points.Point3d;



class Point4d extends Point3d {
	int w;
	public void move(int dx, int dy, int dz, int dw) {
		super.move(dx, dy, dz); w += dw;
	}
}

using the move method of the superclass Point3d to process dx , dy , and dz . If Point4d is written in this way it will compile without errors.

8.2.1.2 Inheritance with public and protected

Given the class Point :


package points;



public class Point {

	public int x, y;


	protected int useCount = 0;


	static protected int totalUseCount = 0;


	public void move(int dx, int dy) {
		x += dx; y += dy; useCount++; totalUseCount++;
	}

}

the public and protected fields x , y , useCount and totalUseCount are inherited in all subclasses of Point . Therefore, this test program, in another package, can be compiled successfully:


class Test extends points.Point {
	public void moveBack(int dx, int dy) {
		x -= dx; y -= dy; useCount++; totalUseCount++;
	}
}


8.2.1.3 Inheritance with private

In the example:


class Point {

	int x, y;


	void move(int dx, int dy) {
		x += dx; y += dy; totalMoves++;
	}


	private static int totalMoves;


	void printMoves() { System.out.println(totalMoves); }

}


class Point3d extends Point {

	int z;


	void move(int dx, int dy, int dz) {
		super.move(dx, dy); z += dz; totalMoves++;
	}

}

the class variable totalMoves can be used only within the class Point ; it is not inherited by the subclass Point3d . A compile-time error occurs at the point where method move of class Point3d tries to increment totalMoves.

8.2.1.4 Accessing Members of Inaccessible Classes

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 if it has 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 .)

Consider the compilation unit:


package points;



public class Point {
	public int x, y;
	public void move(int dx, int dy) {
		x += dx; y += dy;
	}
}

and another compilation unit of another package:


package morePoints;



class Point3d extends points.Point {
	public int z;
	public void move(int dx, int dy, int dz) {
		super.move(dx, dy); z += dz;
	}
}


public class OnePoint {
	static points.Point getOne() { return new Point3d(); }
}

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

Top© 1996 Sun Microsystems, Inc. All rights reserved.