阅前声明: http://blog.csdn.net/heimaoxiaozi/archive/2007/01/19/1487884.aspx
Exercise 1
/****************** Exercise 1 *****************
* Add a new method in the base class of
* Shapes.java that prints a message, but don't
* override it in the derived classes. Explain
* what happens. Now override it in one of the
* derived classes but not the others, and see
* what happens. Finally, override it in all the
* derived classes.
***********************************************/
class
Shape {
void draw() {}
void erase() {}
void print() {
System.out.println("Base-class print()");
}
}
class
Circle extends Shape {
void draw() {
System.out.println("Circle.draw()");
}
void erase() {
System.out.println("Circle.erase()");
}
void print() {
System.out.println("Circle.print()");
}
}
class
Square extends Shape {
void draw() {
System.out.println("Square.draw()");
}
void erase() {
System.out.println("Square.erase()");
}
void print() {
System.out.println("Square.print()");
}
}
class
Triangle extends Shape {
void draw() {
System.out.println("Triangle.draw()");
}
void erase() {
System.out.println("Triangle.erase()");
}
void print() {
System.out.println("Triangle.print()");
}
}
public
class E01_NewShapeMethod {
public static void main(String args[]) {
Shape[] s = {
new Circle(), new Square(), new Triangle(),
};
// Make polymorphic method calls:
for(int i = 0; i < s.length; i++) {
s[i].draw();
s[i].erase();
s[i].print();
}
}
}
//+M java E01_NewShapeMethod
**The above code is the final version, with print( ) overriden in all classes.
**With print( ) defined only in the base class, the output is:
Circle.draw()
Circle.erase()
Base-class print()
Square.draw()
Square.erase()
Base-class print()
Triangle.draw()
Triangle.erase()
Base-class print()
**
Since the base-class version is not being overridden, it is used everywhere.
**With print( ) overridden in Circle, the output is:
Circle.draw()
Circle.erase()
Circle.print()
Square.draw()
Square.erase()
Base-class print()
Triangle.draw()
Triangle.erase()
Base-class print()
**The overridden version is used in Circle, and the default base-class version is used everywhere else.
**If print( ) is overridden everywhere, the result is:
Circle.draw()
Circle.erase()
Circle.print()
Square.draw()
Square.erase()
Square.print()
Triangle.draw()
Triangle.erase()
Triangle.print()
**Thus, the overriden version will always be used if it is available.
Exercise 2
/****************** Exercise 2 *****************
* Add a new type of Shape to Shapes.java and
* verify in main() that polymorphism works for
* your new type as it does in the old types.
***********************************************/
class
Tetrahedron extends Shape {
void draw() {
System.out.println("Tetrahedron.draw()");
}
void erase() {
System.out.println("Tetrahedron.erase()");
}
void print() {
System.out.println("Tetrahedron.print()");
}
}
public
class E02_NewShapeType {
public static void main(String args[]) {
Shape[] s = {
new Circle(), new Square(), new Triangle(),
new Tetrahedron()
};
// Make polymorphic method calls:
for(int i = 0; i < s.length; i++) {
s[i].draw();
s[i].erase();
s[i].print();
}
}
}
//+M java E02_NewShapeType
**Since the other shape definitions are in the same directory (default package) we can just add the new shape and override the methods. The code in the for loop is unchanged from the previous example. The output is:
Circle.draw()
Circle.erase()
Circle.print()
Square.draw()
Square.erase()
Square.print()
Triangle.draw()
Triangle.erase()
Triangle.print()
Tetrahedron.draw()
Tetrahedron.erase()
Tetrahedron.print()
Exercise 3
/****************** Exercise 16 *****************
* Change Music3.java so that what() becomes the
* root Object method toString(). Try printing
* the Instrument objects using
* System.out.println() (without any casting).
***********************************************/
class
Instrument {
public void play() {
System.out.println("Instrument.play()");
}
public String toString() {
return "Instrument";
}
public void adjust() {}
}
class
Wind extends Instrument {
public void play() {
System.out.println("Wind.play()");
}
public String toString() {
return "Wind";
}
public void adjust() {}
}
class
Percussion extends Instrument {
public void play() {
System.out.println("Percussion.play()");
}
public String toString() {
return "Percussion";
}
public void adjust() {}
}
class
Stringed extends Instrument {
public void play() {
System.out.println("Stringed.play()");
}
public String toString() {
return "Stringed";
}
public void adjust() {}
}
class
Brass extends Wind {
public void play() {
System.out.println("Brass.play()");
}
public void adjust() {
System.out.println("Brass.adjust()");
}
}
class
Woodwind extends Wind {
public void play() {
System.out.println("Woodwind.play()");
}
public String toString() {
return "Woodwind";
}
}
public
class E03_MusicToString {
static Instrument[] orchestra = {
new Wind(),
new Percussion(),
new Stringed(),
new Brass(),
new Woodwind()
};
public static void printAll(Instrument[] orch){
for(int i = 0; i < orch.length; i++)
System.out.println(orch[i]);
}
public static void main(String args[]) {
printAll(orchestra);
}
}
//+M java E03_MusicToString
**The output is:
Wind
Percussion
Stringed
Wind
Woodwind
Exercise 4
/****************** Exercise 4 *****************
* Add a new type of Instrument to Music3.java
* and verify that polymorphism works for your
* new type.
***********************************************/
class
Electronic extends Instrument {
public void play() {
System.out.println("Electronic.play()");
}
public String toString() {
return "Electronic";
}
public void adjust() {}
}
public
class E04_NewInstrument {
static Instrument[] orchestra = {
new Wind(),
new Percussion(),
new Stringed(),
new Brass(),
new Woodwind(),
new Electronic()
};
public static void main(String args[]) {
for(int i = 0; i < orchestra.length; i++) {
orchestra[i].play();
orchestra[i].adjust();
System.out.println(orchestra[i]);
}
}
}
//+M java E04_NewInstrument
**The output is:
Wind.play()
Wind
Percussion.play()
Percussion
Stringed.play()
Stringed
Brass.play()
Brass.adjust()
Wind
Woodwind.play()
Woodwind
Electronic.play()
Electronic
Exercise 5
/****************** Exercise 5 *****************
* Modify Music3.java so that it randomly creates
* Instrument objects the way Shapes.java does.
***********************************************/
class
InstrumentGenerator {
public Instrument next() {
switch((int) (Math.random() * 6)) {
default:
case 0:
return new Wind();
case 1:
return new Percussion();
case 2:
return new Stringed();
case 3:
return new Brass();
case 4:
return new Woodwind();
case 5:
return new Electronic();
}
}
}
public
class E05_RandomInstruments {
public static void main(String args[]) {
InstrumentGenerator gen =
new InstrumentGenerator();
for(int i = 0; i < 20; i++)
System.out.println(gen.next());
}
}
//+M java E05_RandomInstruments
**The idea of a generator is a common one. Every time you call it, it produces a new value, but when you call it you don’t give it any parameters.
**One of the flaws with this design is managing the case statement, which is a bit awkward an error-prone. It would be much nicer if we could just index into an array of objects that could themselves generate the different kinds of instruments. This is possible if we use some features of the Class object. Here’s the more elegant solution (that I didn’t expect you to get!):
// A more sophisticated solution using features
// you'll learn about in later chapters.
class
InstrumentGenerator2 {
Class instruments[] = {
Wind.class,
Percussion.class,
Stringed.class,
Brass.class,
Woodwind.class,
Electronic.class,
};
java.util.Random gen = new java.util.Random();
public Instrument next() {
try {
int idx = Math.abs(gen.nextInt())
% instruments.length;
return (Instrument) instruments[idx]
.newInstance();
} catch(Exception e) {
System.out.println("e = " + e);
throw new RuntimeException(
"Cannot Create Instrument");
}
}
}
public
class E05_RandomInstruments2 {
public static void main(String args[]) {
InstrumentGenerator2 gen =
new InstrumentGenerator2();
for(int i = 0; i < 20; i++)
System.out.println(gen.next());
}
}
//+M java E05_RandomInstruments
**References to Class objects for each type of instrument can be produced using the .class that you see in the array. The random number generator method nextInt( ) produces positive and negative numbers covering all 32 bits of an int, so it must be forced to be absolute, and the modulus operator will put it in the range of the array. Class objects have a method newInstance( ) which will create objects of their particular class, but these will throw exceptions. Here, I print the exception but then create and throw a RuntimeException (you’ll learn about exceptions in chapter 10) because I consider it a programming error that doesn’t need to be caught at compile-time.
**Note the benefit of this design – if you need to add a new type to the system, you only need to add it in the Class array; everywhere else takes care of itself.
Exercise 6
/****************** Exercise 6 *****************
* Create an inheritance hierarchy of Rodent:
* Mouse, Gerbil, Hamster, etc. In the base
* class, provide methods that are common to all
* Rodents, and override these in the derived
* classes to perform different behaviors
* depending on the specific type of Rodent.
* Create an array of Rodent, fill it with
* different specific types of Rodents, and call
* your base-class methods to see what happens.
***********************************************/
class
Rodent {
public void hop() {
System.out.println("Rodent hopping");
}
public void scurry() {
System.out.println("Rodent scurrying");
}
public void reproduce() {
System.out.println("Making more Rodents");
}
public String toString() {
return "Rodent";
}
}
class
Mouse extends Rodent {
public void hop() {
System.out.println("Mouse hopping");
}
public void scurry() {
System.out.println("Mouse scurrying");
}
public void reproduce() {
System.out.println("Making more Mice");
}
public String toString() {
return "Mouse";
}
}
class
Gerbil extends Rodent {
public void hop() {
System.out.println("Gerbil hopping");
}
public void scurry() {
System.out.println("Gerbil scurrying");
}
public void reproduce() {
System.out.println("Making more Gerbils");
}
public String toString() {
return "Gerbil";
}
}
class
Hamster extends Rodent {
public void hop() {
System.out.println("Hamster hopping");
}
public void scurry() {
System.out.println("Hamster scurrying");
}
public void reproduce() {
System.out.println("Making more Hamsters");
}
public String toString() {
return "Hamster";
}
}
public
class E06_Rodents {
public static void main(String args[]) {
Rodent[] rodents = {
new Mouse(),
new Gerbil(),
new Hamster(),
};
for(int i = 0; i < rodents.length; i++) {
rodents[i].hop();
rodents[i].scurry();
rodents[i].reproduce();
System.out.println(rodents[i]);
}
}
}
//+M java E06_Rodents
**The output is:
Mouse hopping
Mouse scurrying
Making more Mice
Mouse
Gerbil hopping
Gerbil scurrying
Making more Gerbils
Gerbil
Hamster hopping
Hamster scurrying
Making more Hamsters
Hamster
Exercise 7
/****************** Exercise 7 *****************
* Modify Exercise 6 so that Rodent is an
* abstract class. Make the methods of Rodent
* abstract whenever possible.
***********************************************/
abstract
class Rodent2 {
public abstract void hop();
public abstract void scurry();
public abstract void reproduce();
}
class
Mouse2 extends Rodent2 {
public void hop() {
System.out.println("Mouse hopping");
}
public void scurry() {
System.out.println("Mouse scurrying");
}
public void reproduce() {
System.out.println("Making more Mice");
}
public String toString() {
return "Mouse";
}
}
class
Gerbil2 extends Rodent2 {
public void hop() {
System.out.println("Gerbil hopping");
}
public void scurry() {
System.out.println("Gerbil scurrying");
}
public void reproduce() {
System.out.println("Making more Gerbils");
}
public String toString() {
return "Gerbil";
}
}
class
Hamster2 extends Rodent2 {
public void hop() {
System.out.println("Hamster hopping");
}
public void scurry() {
System.out.println("Hamster scurrying");
}
public void reproduce() {
System.out.println("Making more Hamsters");
}
public String toString() {
return "Hamster";
}
}
public
class E07_AbstractRodent {
public static void main(String args[]) {
Rodent2[] rodents = {
new Mouse2(),
new Gerbil2(),
new Hamster2(),
};
for(int i = 0; i < rodents.length; i++) {
rodents[i].hop();
rodents[i].scurry();
rodents[i].reproduce();
System.out.println(rodents[i]);
}
}
}
//+M java E07_AbstractRodent
**This produces the same output as the previous example. Note that toString( ) is a method of the root class Object and thus can be left out of the abstract base class.