Objectives

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 graphical interface for Simplequiz

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.

The architecture of a simple quiz tool with short-answer questions

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:

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.

The architecture of a simple quiz tool with a parent question class

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:

Examples of interface showing true-false and fill-in-the-blank questions

The architecture of a simple quiz tool with short-answer and fill-in-the-blank questions

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:

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:

Example of the interface showing a multiple-choice question

The new multiple-choice class

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.