Objectives
Students who complete this lab will demonstrate that they can:
- Design and implement inheritance and polymorphic behavior
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 13.1
Create a new package for this lab (
edu.institution.yourLoginID.lab13
) and either import the initial code from the standard code repository or download and unzip the code from
this zip file: startingCode.zip. 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 will build below.
In this hierarchy, we have decided that every question will have some text, and that each kind of question will
return an appropriate string for the getQuestion method. A short answer question will simply return the text, but FillIntheBlank or True/False
questions will augment this question text for the return value of getQuestion() .
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
private
variable myText ;
- It includes a
public accessor method getText() for 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 and its getText() accessor method 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 marked with
@Override
to alert the programming environment that their signatures should match the inherited abstract method
signatures.
- The
getQuestion() accessor method calls the parent method getText() in order to gain access to the text instance variable.
|
Exercise 13.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. Note: The question text itself does not change! Use the getText() accessor to
get the main text of the question,
and then use string concatenation to add "\nFill in the blank." ;
- 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 13.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 13.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 the accessor for 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 13.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 the final version of your music player. We will grade this exercise according to the following criteria:
- Correctness:
- 45% -
exercise 13.2
- Add the required inheritance.
- 40% -
exercise 13.3
- Configure the polymorphic behavior.
- Understandability:
- 5% - Header Documentation - Document the basic purpose, authors and assignment number for your circle
class, console application and unit test class.
- 5% - Code Documentation - Separate the logical blocks of your program with useful comments and white space.
- 5% - Method Documentation - Document the circle class’s methods.
- Extra Credit: up to 10% added to your score (5% per exercise)