Suppose that we have two types of fish movement that we would like to model. The first is a fish that follows a path, going from one location to another in the environment. A second is a fish that follows another fish. As we discuss these possibilities, we realize that these two fish have one part of their movement behavior in common, on any given move, a fish of either type wants to move toward a specific location, its goal as it were. In the case of the fish following a path, the goal is the next location on the path. In the case of the "hunter" fish that follows another fish, its goal on a given move is the current location of its "target," the fish it is following.
When we analyze the development of related classes like these and see some characteristics in common, it suggests a design where we put the common elements into an abstract class and then a class representing each type of fish with the common behavior extend that common, probably abstract, class. First we specify the two types of fish.
This type of fish is assigned another fish as a "target" when it is constructed (this means that some other fish must exist before this fish is created). A simple version might assign as a target a randomly selected fish from among those that already exist (meaning this type of fish cannot be the first created in the model). Another version might pass the target as a parameter to the constructor. This fish will then always move to an empty neighboring location that puts it closer to its target. If this is not possible, it does not move.
This type of fish has a list of locations that it visits in order, then starts again at the beginning of the list. The list can be passed as a parameter to the constructor. This fish will then always move to an empty neighboring location that puts it closer to its the current location in its list. If this is not possible, it does not move.
The last two sentences of these two specifications are practically the same!
Describe an inheritance hierarchy that consists of an abstract class (GoalSeeker ?) that encapsulates the common features of these two specifications, and a class representing each of the two types of fish that extends this abstract class so as to implement its specification. Your descriptiuon should clearly indicate the methods and the instance variables (if any) for each class. An annotated diagram is a good way to represent this design.
Write the code for the three classes in this inheritance hierarchy.
Think of another type of fish that shares the same common goal-seeking aspect of this behavior, add it to the inheritance hierarchy. Code your new class.
You can test these fish classes using the SimpleMBSDemo2 driver class or by adding them to the arrays in the MBSGUI class as described in its comments.