Objectives
- to introduce inheritance and polymorphism
In this lab exercise, you’ll use all three of the object-oriented capabilities to
design and implement a system that controls a simple quiz application.
The Simplequiz Application
In this lab, you will work with a quiz application that asks a sequence of questions of the
user. The interface is shown here:
The application displays questions in a large text area (on the top) and messages (on the
bottom right); the user types answers in a text box (on the bottom left) and presses enter.
The classes that implement this application are shown here.
Take time now to review the complete API specification for these
classes. Note that Simplequiz
randomizes its questions for each run by calling the
predefined Collections class method Collections.shuffle()
.
Exercise 12.1
Create a new package for this lab (edu.institution.yourLoginID.lab12
)
and import the initial code from the standard code repository. As usual, you’ll need to modify
the package specifications. Now, familiarize yourself with the quiz mechanism by doing the
following:
- Run the quiz GUI controller a couple of times;
- Run the unit tests;
- Add a new short-answer question of your choice.
Save this code for use in the next exercise.
Inheritance
In preparation for the addition of other types of questions (e.g., true-false questions), you
will now implement a parent Question
class that collects all the data items and method
specifications that ShortAnswerQuestion
can share with other question objects. The
first version of the question class hierarchy is shown here.
|
This structure contains two classes in which ShortAnswerQuestion inherits from
Question . You can see in the diagram that the original ShortAnswerQuestion
has been modified by moving its most general features up into the Question class so
that they can be shared by the other question classes that you build below.
To build the classes shown in the figure, note the following:
- The
Question class is a new class with the following features:
- It is an abstract class;
- It includes a constructor method that receives a String and stores it in the
protected
variable myText ;
- It includes abstract method specifications for
getQuestion() , getAnswer()
and checkAnswer() , whose signatures should match those used in the original ShortAnswerQuestion ;
- The
ShortAnswerQuestion class is just like the original with the following
modifications:
- It now extends the
Question class;
- It inherits
myText from Question so it doesn’t need to
implement it anymore;
- Its constructor method starts with a call to
super(text) , where text
is the parameter holding the question text;
- Its three concrete method definitions are the same as they were before, but they are
marked with
@Override to alert the programming environment that their signatures
should match the inherited abstract method signatures.
|
Exercise 12.2
Refactor your Simplequiz application to include Question
and ShortAnswerQuestion
classes as specified above. The application should run just as it did before and its unit tests
should still pass.
Save this code for use in the next exercise.
Polymorphism
You can now add more types of questions, such as true-false questions and fill-in-the-blank
questions. Examples of how Simplequiz should present these question types are shown here:
|
Your new question classes are similar to ShortAnswerQuestion , but they must
implement the three abstract methods specified by Question each in their own unique
way:
- The
FillInBlankQuestion class is just like the ShortAnswerQuestion
class with the following modifications:
- Its
getQuestion() method must append the string "\nFill in
the blank." to the end of the question text;
- The
TrueFalseQuestion class is just like the ShortAnswerQuestion
class with the following modifications:
- Its
myAnswer data attribute is a boolean and the explicit-value
constructor receives a boolean value for the answer;
- Its
getQuestion() method must append the string "\nIs this
statement true or false?" to the end of the question text;
- Its
getAnswer() method must still return a string (to match the abstract
method it is overriding), so it needs to cast the boolean answer into a string (i.e., into "true"
or "false" ) - you can do this using new Boolean(myAnswer).toString() ;
- Its
checkAnswer() method must compare the string received from the calling
program (answer ) against a string version of the correct answer - you can do this
using getAnswer().equalsIgnoreCase(answer) ).
You don’t need to change the quiz mechanism in any way because it is using the
standard API specified in Question to manipulate the questions. That is, it is using
getQuestion() , getAnswer() and checkAnswer() as specified
by the abstract methods inherited by all sub-classes of Question .
|
Exercise 12.3
For this exercise, do the following:
- Add the
FillInBlankQuestion
and TrueFalseQuestion
classes as
specified above;
- Modify
Simplequiz
to store a list of Question
objects (rather
than the list of only ShortAnswerQuestion
objects it currently has);
- Add at least one sample question for each of the two new question types.
Your quiz should now operate just as it did before, with randomly ordered questions of
various types. Save this version of your program to turn in.
Java should now invoke the correct definition of the question methods based on which Question
sub-class it is working with.
Exercise 12.4 (Extra Credit)
Add test cases to the SimplequizTest
unit test class that exercise your new Question
sub-classes. To verify that Java implements the polymorphism correctly, declare your test question
objects as Question
objects rather than as objects of one of the concrete Question
sub-classes; Java should still invoke the correct definitions.
Save this version of your program for extra credit.
Multiple-Choice Questions (Extra Credit)
For extra credit, you can add a multiple choice question class as shown here:
|
The new MultipleChoiceQuestion class is somewhat more complicated than the
other question types, but you can still implement it as a child of Question . For one
approach to doing this, see the diagram on the left and the following implementation notes:
- The
MultipleChoiceQuestion class must store a list of strings that comprise
the choices;
- The constructor method initializes an empty list of choices and lets the
addChoice()
method add as many choices at the Simplequiz class wants to add;
- The
addChoice() method receives a choice string and a boolean indicating
whether or not this choice is the correct one. Only one choice can be correct;
- The
getQuestion() method constructs the full question from myText
plus a numbered list of choices plus the instructions string (i.e., "Enter the best
choice." );
- The
checkAnswer() method must compare the string the user types (e.g., "2" )
with myAnswerIndex (an integer) - you can do this using Integer.parseInt(index)
== myCorrectIndex ;
- The ambitious student can randomize the order of the choices for additional
extra credit - you can use
Collections.shuffle() to do this, but you’ll need
to find a way to determine the new value for myAnswerIndex .
|
Exercise 12.5 (Extra Credit)
Implement an multiple-choice question class, add an example of it to Simplequiz
and save this version of your program for extra credit.
Checking In
Submit all the code and supporting files for the exercises in this lab.