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 allRodent
s, and override these in the derived classes to perform different behaviors depending on the specific type ofRodent
s. Create an array ofRodent
, fill it with different specific types ofRodent
s, 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
|