<< Chapter < Page | Chapter >> Page > |
The above can be modeled by a Queen class with an abstract Worker inner class as shown below. This example illustrates the differences between static and non-static fields, methods and embedded classes.
Queen.java
/**
* Models ants living in a 1-dimensional world*
** The Worker inner objects have direct access to the location of its outer
* Queen object.*
* @author A.L. Cox* @author D.X. Nguyen
* @author S.B. Wong* @since 02/07/2003
*/public class Queen {
/*** The total number of ants (queens and workers for all the queens) that
* currently exist in our ant world.*
* Why is this field static?*/
private static int _ants;/**
* The location of this Queen object with respect to 0.*
* Why is this field non-static?*/
private int _origin;/**
* The total numbers of living worker ants produced by this Queen object.*
* Why is this field non-static?*/
private int _workers;/**
* Is part of a Queen instance, just like the origin field and the* makeWorker() method are parts of a Queen instance.
* Any concrete implementation of Worker must implement the getName()* method to return the name given by its Queen at birth time.
** Why can't this class be static?
*/public abstract class Worker {
/*** The location of this Worker object.
*/private int _location;
/*** Increments _ants and _workers because every time a Worker is
* instantiated, a new ant is added to our ant world, a new worker ant* is added to the colony of this outer Queen object.
* @param loc the starting location of this Worker object.*/
public Worker(int loc) {_location = loc;
_ants++; // The worker is an ant._workers++;
}/**
* @return the relative distance between this Worker and its outer Queen* object.
*/public int calcDist() {
return _location - _origin;}
/*** The name will be given at birth. The code cannot be written at
* this point and thus must be abstract.* @return name of the worker
*/public abstract String getName();
/*** Our worker has been stepped on! (No one holds a reference
* to this object anymore. It's being garbage collected.)*/
protected void finalize() {_ants--; // The worker is an ant.
_workers--;}
/*** Changes the location of this Worker object to a new location.
* @param loc the new location for this Worler object.*/
public void moveTo(int loc) {_location = loc;
}/**
* Changes the origin of the outer Queen object to a new location.* @param org the new origin for the outer Queen object.
*/public void moveQueen(int org) {
moveTo(org);_origin = org;
}}
/*** Initializes the origin of this Queen object to a given location.
* Increments _ants since this new Queen object is an ant.* @param org the starting origin of this Queen object.
*/public Queen(int org) {
_ants++; // The queen is an ant._origin = org;
}/**
* Return the total number of all ants, including all of the* queens and their respective workers.
** Why is this method static?
* Can it be non-static?*/
public static int countAllAnts() {return _ants;
}/**
* @return the total number of workers thatbelong to this Queen object
** Why isn't this method static?
*/public int countMyWorkers() {
return _workers;}
/*** Factory method: relegate the task of manufacturing concrete
* Worker objects to the Queen object because the Queen object* intrinsically "knows" how to make its inner objects.
* @param name The name of the Worker.*/
public Worker makeWorker(final String name) {// Anonymously create a Worker object by overriding getName().
return new Worker(_origin) {public String getName() {
return name; // requires the parameter name to be final.}
};}
}
Notification Switch
Would you like to follow the 'Principles of object-oriented programming' conversation and receive update notifications?