11. Inheritance and Polymorphism

11.8. Principles Of Object-Oriented Design

To conclude this chapter, it will be helpful to focus briefly on how the examples we’ve seen address the various object-oriented design (OOD) principles we set out at the beginning of the book.

Divide-and-Conquer Principle. Notice how all of the problems tackled in this chapter have been solved by dividing them into sev- eral classes, with each of the classes divided into separate methods. The very idea of a class hierarchy is an application of this principle.

Encapsulation Principle. The superclasses in our designs, Cipher

and TwoPlayerGame, encapsulate those features of the class hier-

 

SECTION 8.7 Principles Of Object-Oriented Design385

archy that are shared by all objects in the hierarchy. The subclasses, CaesarCipher and OneRowNim, encapsulate features that make them distinctive with the class hierarchy.

Interface Principle. The several Java interfaces we’ve designed, IPlayer, CLUIPlayableGame and UserInterface, specify clearly how various types of related objects will interact with each other through the methods contained in the interfaces. Clean inter- faces make for clear communication among objects.

Information Hiding Principle. We have continued to make con- sistent use of the private and public qualifiers, and have now introduced the protected qualifier to extend this concept. The in- heritance mechanism gives subclasses access to protected and public elements of their superclasses.

Generality Principle. As you move down a well-designed class hi- erarchy, you go from the more general to the more specific features of the objects involved. The abstract encode() method specifies the gen- eral form that encoding will take while the various implementations of this method in the subclasses provide the specializations neces- sary to distinguish, say, Caesar encoding from Transpose encoding. Similarly, the abstract makeAMove() method in the IPlayer inter- face provides a general format for a move in a two-player game, while its various implementations provide the specializations that distinguish one game from another.

Extensibility Principle. Overriding inherited methods and imple- menting abstract methods from either an abstract superclass or a Java interface provide several well-designed ways to extend the functionality in an existing class hierarchy. Extending a class is a form of specialization of the features inherited from the superclass.

Abstraction Principle. Designing a class hierarchy is an exercise in abstraction, as the more general features of the objects involved are moved into the superclasses. Similarly, designing a Java interface or an abstract superclass method is a form of abstraction, whereby the signature of the method is distinguished from its various implemen- tations.

These, then, are some of the ways that the several examples we have considered and this chapter’s discussion have contributed to a deepening of our understanding of object-oriented design.

 

 

 

 

CHAPTER SUMMARYTechnical Terms

abstract method actual type (dynamic

type) ciphertext

class inheritance cryptography


 

dynamic binding (late binding)

interface overloaded method plaintext

polymorphic method polymorphism


 

static binding (early binding)

static type (declared type)

substitution cipher transposition cipher

 

Summary of Important Points

Inheritance is an object-oriented mechanism whereby subclasses in- herit the public and protected instance variables and methods from their superclasses.

Dynamic binding (or late binding) is the mechanism by which a method call is bound to (associated with) the correct implementation of the method at run time. In Java, all method calls, except for final or private methods, are resolved using dynamic binding.

Static binding (or early binding) is the association of a method call with

its corresponding implementation at compile time.

Polymorphism is an object-oriented language feature in which a method call can lead to different actions depending on the object on which it is invoked. A polymorphic method is a method signature that is given different implementation by different classes in a class hierarchy.

A static type is a variable’s declared type. A dynamic type, or actual type, is the type of object assigned to that variable at a given point in a running program.

An abstract method is a method definition that lacks an implemen- tation. An abstract class is one that contains one or more abstract methods. An abstract class can be subclassed but not instantiated. A Java interface is a class that contains only method signatures and (possibly) constant declarations, but no variables. An interface can be implemented by a class by providing implementations for all of its abstract methods.

 

 

 

SOLUTIONS TO

SELF-STUDY EXERCISES


SOLUTION 8.1 Running the TestPrint program will produce the output shown here. It is clear that the inherited toString() method is used by println() when printing a TestPrint object.

,,

 

 

J

 

SOLUTION 8.2 If you override the toString() method in TestPrint, you should get something like the output shown here, depending on how you code

 

CHAPTER 8 Solutions to Self-Study Exercises387

toString(). It is clear that the toString() method is used polymorphously by println().

,,

 

J

 

 

SOLUTION 8.3 The output produced when constructing objects of type A and B in the order shown in the exercise would be as follows, with each letter occurring on a separate line:

,,

 

J

 

 

SOLUTION 8.4 The new implementation of B’s method() will invoke A’s ver- sion of the method before printing B. This will print “A A B A B”.

,,

 

 

 

J

 

 

SOLUTION 8.5 Give the definitions of classes A and B in the exercise, the marked statements would be invalid:

,,

 

 

 

J

 

 

SOLUTION 8.6 Given the class definitions and code segment in this exercise, the output would be, A A B A B C, with each letter printing on a separate line.

 

 

SOLUTION 8.7 Definition of an Pig subclass of Animal:

,,

 

 

 

 

 

J

 

SOLUTION 8.8 If polymorphism was not used in our design, the talk() method would have to be modified to the following in order to accommodate a Pig subclass:

,,

 

 

 

 

 

 

 

J

 

 

SOLUTION 8.9 Code to swap two boolean variables:

,,

 

 

J

 

 

SOLUTION 8.10 Creating a ToggleButton that can be used to deal or collect cards:

,,

 

 

 

J

 

 

SOLUTION 8.11 Modify the Caesar class so that it will allow various-sized shifts to be used.

,,

 

 

 

 

 

J

 

 

SOLUTION 8.12 Modify Transpose.encode() so that it uses a rotation in- stead of a reversal. The operation here is very similar to the shift operation in the Caesar cipher. It uses modular arithmetic to rearrange the letters in the word. For example, suppose the word is “hello”. Its letters are indexed from 0 to 4. The

 

following table shows how the expression ((k+2) % 5) will rearrange the letters as k varies from 0 to 4:

,,

 

 

 

 

 

 

 

 

 

 

J

SOLUTION 8.13 A NimPlayer class that plays the optimal OneRowNim game would be identical to the NimPlayerBad class except the move():int method would be replaced with the following implementation:

,,

 

 

 

 

 

 

 

 

 

 

EXERCISE 8.1 Fill in the blanks in each of the following sentences:

A method that lacks a body is anmethod.

Anis like a class except that it contains only instance methods, no instance variables.

Two ways for a class to inherit something in Java is toa class and

an interface.

Instance variables and instance methods that are declaredor

are inherited by the subclasses.

An object can refer to itself by using thekeyword.

If a GUI class intends to handle ActionEvents, it must implement the

interface.

Amethod is one that does different things depending upon the object that invokes it.

EXERCISE 8.2 Explain the difference between the following pairs of concepts:


EXERCISES

Note: For programming exercises, first draw a UML class diagram describing all classes and their inheritance relationships and/or associations.

 

Class and interface.

Stub method and abstract method.

Extending a class and instantiating an object.

Defining a method and implementing a method.

A protected method and a public method.

A protected method and a private method.

EXERCISE 8.3 Draw a hierarchy to represent the following situation. There are lots of languages in the world. English, French, Chinese, and Korean are exam- ples of natural languages. Java, C, and C++ are examples of formal languages. French and Italian are considered romance languages, while Greek and Latin are considered classical languages.

 

EXERCISE 8.4 Look up the documentation for the JButton class on Sun’s Web site:

,,

 

J

List the names of all the methods that would be inherited by the ToggleButton

subclass that we defined in this chapter.

 

EXERCISE 8.5 Design and write a toString() method for the ToggleButton class defined in this chapter. The toString() method should return the ToggleButton’s current label.

EXERCISE 8.6 Design a class hierarchy rooted in the class Employee that in- cludes subclasses for HourlyEmployee and SalaryEmployee. The attributes shared in common by these classes include the name, and job title of the employee, plus the accessor and mutator methods needed by those attributes. The salaried employees need an attribute for weekly salary, and the corresponding methods for accessing and changing this variable. The hourly employees should have a pay rate and an hours worked variable. There should be an abstract method called calculateWeeklyPay(), defined abstractly in the superclass and implemented in the subclasses. The salaried worker’s pay is just the weekly salary. Pay for an hourly employee is simply hours worked times pay rate.

 

EXERCISE 8.7 Design and write a subclass of JTextField called Integer- Field that is used for inputting integers but behaves in all other respects like a JTextField. Give the subclass a public method called getInteger().

EXERCISE 8.8 Implement a method that uses the following variation of the Cae- sar cipher. The method should take two parameters, a String and an int N. The result should be a String in which the first letter is shifted by N, the second by N + 1, the third by N + 2, and so on. For example, given the string “Hello,” and an initial shift of 1, your method should return “Igopt.”

Write a method that converts its String parameter so that letters are written in blocks five characters long.

 

EXERCISE 8.9 Design and implement an GUI that lets the user type a document into a TextArea and then provides the following analysis of the document: the number of words in the document, the number of characters in the document, and the percentage of words that have more than six letters.

 

EXERCISE 8.10 Design and implement a Cipher subclass to implement the fol- lowing substitution cipher: Each letter in the alphabet is replaced with a letter from the opposite end of the alphabet: a is replaced with z, b with y, and so forth.

 

EXERCISE 8.11 One way to design a substitution alphabet for a cipher is to use a keyword to construct the alphabet. For example, suppose the keyword is “zebra.” You place the keyword at the beginning of the alphabet, and then fill out the other 21 slots with remaining letters, giving the following alphabet:

,,

 

J

Design and implement an Alphabet class for constructing these kinds of sub- stitution alphabets. It should have a single public method that takes a keyword String as an argument and returns an alphabet string. Note that an alphabet cannot contain duplicate letters, so repeated letters in a keyword like “xylophone” would have to be removed.

EXERCISE 8.12 Design and write a Cipher subclass for a substitution cipher that uses an alphabet from the Alphabet class created in the previous exercise.

EXERCISE 8.13 Challenge: Find a partner and concoct your own encryption scheme. Then work separately with one partner writing encode() and the other writing decode(). Test to see that a message can be encoded and then decoded to yield the original message.

EXERCISE 8.14 Design a TwoPlayerGame subclass called Multiplication- Game. The rules of this game are that the game generates a random multiplication problem using numbers between 1 and 10, and the players, taking turns, try to provide the answer to the problem. The game ends when a wrong answer is given. The winner is the player who did not give a wrong answer.

EXERCISE 8.15 Design a class called MultiplicationPlayer that plays the multiplication game described in the previous exercise. This class should imple- ment the IPlayer interface.

EXERCISE 8.16 Design a TwoPlayerGame subclass called RockPaperScis- sors. The rules of this game are that each player, at the same time, picks either a rock, a paper, or a scissors. For each round, the rock beats the scissors, the scissors beats the paper, and the paper beats the rock. Ties are allowed. The game is won in a best out of three fashion when one of the players wins two rounds.

EXERCISE 8.17 Design a class called RockPaperScissorsPlayer that plays the the game described in the previous exercise. This class should implement the IPlayer interface.

 

 

 

 

 

 

 

 

 

 

 

Chapter 9