|
|
|
Sponsored Link •
|
Cup
will work with a CoffeeCup, because a CoffeeCup
is-a Cup.
Liquid myFavoriteBeverage = new Coffee();
Coffee reference is being
cast up the inheritance hierarchy to a Liquid reference.
add() gets invoked?
Liquid myFavoriteBeverage = new Coffee(); myFavoriteBeverage.add(new Milk(25));
myFavoriteBeverage,
is Liquid.
Coffee.
add() gets invoked?Liquid myFavoriteBeverage = new Coffee(); myFavoriteBeverage.add(new Milk(25));
<init> methods, and super
invocations.
1 // In file PolymorphInt/examples/ex1/Liquid.java
2 public class Liquid {
3
4 void swirl(boolean clockwise) {
5
6 // Implement the default swirling
7 // behavior for liquids
8 System.out.println(
9 "Swirling Liquid");
10 }
11 }
1 // In file PolymorphInt/examples/ex1/Coffee.java
2 class Coffee extends Liquid {
3
4 void swirl(boolean clockwise) {
5
6 // Simulate the peculiar swirling
7 // behavior exhibited by Coffee
8 System.out.println(
9 "Swirling Coffee");
10 }
11 }
1 // In file PolymorphInt/examples/ex1/Milk.java
2 class Milk extends Liquid {
3
4 void swirl(boolean clockwise) {
5
6 // Model milk's manner of swirling
7 System.out.println("Swirling Milk");
8 }
9 }
1 // In file PolymorphInt/examples/ex1/Cup.java
2 class Cup {
3
4 private Liquid innerLiquid;
5
6 Cup(Liquid liq) {
7 innerLiquid = liq;
8 // Swirl counterclockwise
9 innerLiquid.swirl(false);
10 }
11 }
1 // In file PolymorphInt/examples/ex1/Example1.java
2 class Example1 {
3
4 public static void main(String[] args) {
5
6 // First you need various kinds
7 // of liquid
8 Liquid liquid = new Liquid();
9 Liquid coffee = new Coffee();
10 Liquid milk = new Milk();
11
12 // Now create cups that contain
13 // various kinds of liquid
14 Cup cup1 = new Cup(liquid);
15 Cup cup2 = new Cup(coffee);
16 Cup cup3 = new Cup(milk);
17 }
18 }
Example2 application will be:Swirling Liquid Swirling Coffee Swirling Milk
abstract keyword:
1 // In file PolymorphInt/examples/ex2/Animal.java
2 public abstract class Animal {
3
4 public void talk() {
5 System.out.println("Hi there.");
6 }
7 }
8
1 // In file PolymorphInt/examples/ex2/Dog.java
2 public class Dog extends Animal {
3
4 public void talk() {
5 System.out.println("Woof!");
6 }
7 }
8
1 // In file PolymorphInt/examples/ex2/Cat.java
2 public class Cat extends Animal {
3
4 public void talk() {
5 System.out.println("Meow.");
6 }
7 }
8
1 // In file PolymorphInt/examples/ex2/Example2.java
2 public abstract class Example2 {
3
4 public static void main(String[] args) {
5
6 Animal dog = new Dog();
7 Animal cat = new Cat();
8
9 // THIS WOULDN'T COMPILE
10 // Animal animal = new Animal();
11
12 dog.talk();
13 cat.talk();
14 }
15 }
16
1 // In file PolymorphInt/examples/ex3/Animal.java
2 public abstract class Animal {
3
4 public abstract void talk();
5 }
6
1 // In file PolymorphInt/examples/ex3/Dog.java
2 public class Dog extends Animal {
3
4 public void talk() {
5 System.out.println("Woof!");
6 }
7 }
8
1 // In file PolymorphInt/examples/ex3/Cat.java
2 public class Cat extends Animal {
3
4 public void talk() {
5 System.out.println("Meow.");
6 }
7 }
8
1 // In file PolymorphInt/examples/ex3/Example3.java
2 public abstract class Example3 {
3
4 public static void main(String[] args) {
5
6 Animal dog = new Dog();
7 Animal cat = new Cat();
8
9 // THIS WOULDN'T COMPILE
10 // Animal animal = new Animal();
11
12 dog.talk();
13 cat.talk();
14 }
15 }
16
1 // In file PolymorphInt/examples/ex4/Washable.java
2 interface Washable {
3
4 int MAX_SUDS = 10;
5
6 // Returns true if the object needs to be
7 // washed
8 //
9 boolean needsWashing();
10
11 // Washes the object
12 //
13 void wash();
14 }
15
1 // In file PolymorphInt/examples/ex4/Washable.java
2 interface Washable {
3
4 int MAX_SUDS = 10;
5
6 // Returns true if the object needs to be
7 // washed
8 //
9 boolean needsWashing();
10
11 // Washes the object
12 //
13 void wash();
14 }
15
1 // In file PolymorphInt/examples/ex4/Cup.java
2 public abstract class Cup {
3
4 private int innerLiquid;
5
6 public void add(int amount) {
7 //...
8 }
9
10 public int releaseOneSip(int sipSize) {
11 //...
12 return 0;
13 }
14
15 public int spillEntireContents() {
16 //...
17 return 0;
18 }
19 }
20
1 // In file PolymorphInt/examples/ex4/CoffeeCup.java
2 public class CoffeeCup extends Cup
3 implements Washable {
4
5 public boolean needsWashing() {
6 return true;
7 }
8
9 public void wash() {
10 //...
11 }
12 }
13
extends keyword:
1 // On CD-ROM in file interface/ex8/Washable.java
2 interface Washable {
3 void wash();
4 }
5
1 // On CD-ROM in file interface/ex8/Soakable.java
2 interface Soakable extends Washable {
3 void soak();
4 }
5
1 // On CD-ROM in file interface/ex8/Scrubable.java
2 interface Scrubable extends Washable {
3 void scrub();
4 }
5
1 // On CD-ROM in file interface/ex8/BubbleBathable.java
2 interface BubbleBathable extends Soakable, Scrubable {
3 void takeABubbleBath();
4 }
5
implements keyword:
1 // On CD-ROM in file interface/ex8/Washable.java
2 interface Washable {
3 void wash();
4 }
5
1 // On CD-ROM in file interface/ex8/Soakable.java
2 interface Soakable extends Washable {
3 void soak();
4 }
5
1 // On CD-ROM in file interface/ex8/Scrubable.java
2 interface Scrubable extends Washable {
3 void scrub();
4 }
5
1 // On CD-ROM in file interface/ex8/BubbleBathable.java
2 interface BubbleBathable extends Soakable, Scrubable {
3 void takeABubbleBath();
4 }
5
1 // In file PolymorphInt/examples/ex5/Breakable.java
2 interface Breakable {
3 void breakIt();
4 }
5
1 // In file PolymorphInt/examples/ex5/CoffeeCup.java
2 class CoffeeCup
3 implements BubbleBathable, Breakable {
4
5 public void wash() {
6 }
7
8 public void soak() {
9 }
10
11 public void scrub() {
12 }
13
14 public void takeABubbleBath() {
15 }
16
17 public void breakIt() {
18 }
19 }
20
CoffeeCup had neglected to implement all methods
declared or inherited by BubbleBathable and
Breakable, CoffeeCup would have to
be declared abstract.
Take the code from Problem 4 from the Composition and Inheritance exercises
and replace class Rodent with an interface. To refresh your
memory, here's Problem 4 from Composition and Inheritance:
Create an inheritance hierarchy of
Rodent:Mouse,Gerbil,Hamster, etc. In the base class, provide methods that are common to allRodents, and override these in the derived classes to perform different behaviors depending on the specific type ofRodents. Create an array ofRodent, fill it with different specific types ofRodents, and call your base-class methods to see what happens.
In a class named Dictionary (in a file named
Dictionary.java), create a class (static) variable
named WORD_COUNT of type long. Make
WORD_COUNT public and final. Initialize WORD_COUNT
in a static initializer to the value 1234567. (A static
initializer is just an "= <value>" after
the declaration of the static variable and before the semicolon. Create
a static initialization block inside Dictionary that prints
the value of WORD_COUNT out to the standard output with
this string message: "Dictionary: WORD_COUNT == <value>".
Create a
class named SpellChecker (in a file named
SpellChecker.java) that has a main() method
of the usual signature (public, static, void, a String
array as its only parameter). In the main() method, print
the value of Dictionary.WORD_COUNT to the standard output
with this message: "SpellChecker: WORD_COUNT == <value>".
Compile these classes and run them to see the output. Take a moment to ponder the deep significance of this output.
In class SpellChecker from Problem 2, create a new
Dictionary object with the new keyword. Place this
new statement first in the main method. Store the
reference returned from new in a local variable.
Compile these classes again and run them to see the output. Why is this output different from that of Problem 2?
Since you've been having so much fun with Dictionary and
SpellChecker, please return to this code one last time. Take
the classes from
Problem 3 and edit Dictionary.java. Change the value of
WORD_COUNT in Dictionary to 7654321.
Recompile just Dictionary.java. It is important that you
compile Dictionary.java without recompiling
SpellChecker.java. Make sure you type:
javac Dictionary.java
Run the SpellChecker program one last time and observe
its startling output. What went wrong?
In the PolymorphInt/examples/ex1 directory of the sample
code, create a class Tea that extends Liquid.
Define a swirl() method in Tea that overrides
Liquid's implementation. In the body of Tea's
swirl() method, just print "Swirling Tea" to
the standard output.
Edit Example1.java in the PolymorphInt/examples/ex1
directory. At the end of the main() method, add two more
statements. In the first statement, create a new Tea instance
and store the reference in a local variable. In the second statement,
create a new Cup instance, passing a reference to
the Tea object to Cup's constructor.
Execute the Example1 application and observe the results.
In the PolymorphInt/examples/ex5 directory, create a
new class Puppy. Make Puppy implement
Bubblebathable, but don't actually implement any
methods in the body of Puppy (just declare that
"Puppy implements Bubblebathable". Attempt to compile
your program and observe the error messages generated by the compiler.
In the Puppy.java class from Problem 6, implement whatever
methods you need to implement to get class Puppy to compile.
In each method, just print out a message to the standard output saying
which method is being called, such as "Puppy: wash() invoked.".
Type in this Problem7 application and run it:
class Problem7 {
public static void main(String[] args) {
Puppy puppy = new Puppy();
soakIt(puppy);
}
public static void soakIt(Soakable s) {
s.wash();
s.soak();
}
}
Copy Problem7.java to Problem8.java, and rename the
class it contains Problem8. Changing only the body
of the soakIt() method in class Problem8, find a way to invoke, in addition
to wash() and soak(), the
takeABubbleBath() method on any passed object that happens
to implement BubbleBathable. (Do not change the
type of the passed s parameter. Your revised soakIt()
method should also accept a Soakable reference.)
Run the Problem8
program and observe the output.
|
Sponsored Links
|