Lab 2: Inheritance

The goal of this lab is to explore options for code reuse, including inheritance. This lab also gives practice using Eclipse and SVN.

1. Set up

Make a directory for this lab and move into it. In this lab, you obtain the starter code using SVN, and you will also turn in your code using SVN. Do the following (in the command line) to checkout the code:

svn checkout file:///homes/tvandrun/Public/cs245/lab-repos/####

where ##### is the lab account you're using, for example "cs235a".

Now, open Eclipse. You can launch it either from the command line or through Applications->Programming->Eclipse. Since this will probably be the first like Eclipse is opened for the lab account, it will pick a default location for the workspace. You may chose to keep the default location or pick a new one.

After Eclipse loads, you will get a screen that looks something like this:

Click on the archy arrow all the way to the right. This will bring you to the work bench.

Now, start a new Java project. Select "create project from existing source" and enter or browse to the directory where you checked out the code. Click finish.

2. The redundant code

Take a moment to re-familiarize yourselves with the code. To run it, under the green-arrow button, select "run configurations". Double-clock on "Java Application", and under the "Arguments" tab, type in "easy" under "Program arguments:". This passes the string "easy" on the command line, which tells the program to load the puzzle in the file of that name.

In particular, notice how OpenEntry and GivenEntry contain redundant code. Take note of what instance variables and what implementation of methods they have in common. Similarly take stock of the similarities between RowColumn and Square.

3. Fixing the redundant code using composition

Our first attempt to fix this is going to use a technique called composition. The main idea is that we are going to take those things that are common between RowColumn and Square and package them up into their own class.

Make a new class, SRCShare, which will contain the shared code bewteen Square and RowColumn. The class SRCShare must contain three things:

The idea is that each Square and RowColumn object will have and SRCShare object as a component.

Now, in both the class Square and the RowColumn rewrite the repeated parts so that they make use of SRCShare Instead of an entries ArrayList, they should each have an instance variable of type SRCShare. They should instantiate SRCShare in their constructors. Moreover, the actionPerformed() methods should delegate some of their work to SRCShare.

Now, what should that method in SRCShare return? Well, what information do the actionPerformed() methods need? They need to know (a) whether there is any violation, and, if not, (b) whether there are any unknowns. So, really the method in SRCShare needs to return two boolean values. Here's a hack to accomplish this: Make the method to return a boolean array. The array should be of size 2, and the 0th position can indicate whether there are any violations, the 1th position whether there are any unknowns.

Finish these changes, make sure all classes you've written or modifies are adquately documented, and make sure the program runs as it did before. Finally, commit your changes. To do this, right-click on the sudoku project, select "Team", and select "Commit."

Now, consider what you did in this part. You shipped the commonality between two classes into a third class and then made the two original classed to be composed from the third class. This is known as composition, and usually it is a very good way to allow two classes to share code. In this particular example, however, it turns out to be fairly clunky. It also wouldn't work very well to use it on the commonality between GivenEntry and OpenEntry.

4. Inheritance and abstract classes.

Revert your code back to the original version. Now we are going to focus on GivenEntry and OpenEntry. The similarity they have is that they both have a value which they need to return through a getter method, and they both have a method called display().

Make a new class called Entry, and in the new-class wizard, indicate that this class is to be abstract.

In the Entry class, make an instance variable String value like in GivenEntry and OpenEntry, but instead of being private, make it protected. Make a getter method value(). Also, add the following line:

    public abstract Component display();

Notice that line looks like a method signature from an interface. In fact, it is, although we call it an abstract method in this context. An abstract class is something that is half-way between being an interface and a class. Alternately, you can think of it as a partially written class. Just as we have seen classes that implement interfaces, we will now see classes that extend abstract classes. This means that

We call this class extension or inheritance. The idea is that the classes that extend the abstract class inherit the members in the abstract class. The abstract class is called the parent class or super class; the classes that extend the abstract class are called child classes or subclasses.

The access modifier protected means that the member is accessible to the child class, but not to the outside world. (If a member of an abstract class is declared private, then any child class of that abstract class still inherit that member, but the member is inaccessible to the child class. Why would you ever want to do that? We'll see some examples later this semester.)

Now, go to the classes GivenEntry and OpenEntry. Change them so that they extend Entry, that is

public class OpenEntry extends Entry implements ActionListener {

Also, delete the value instance variables, and the value() methods, since they are inherited.

Test to see that it all compiles and still works. When you're confident it works right, now try to write a superclass for RowColumn and Square called Container. Ask for help as you go along.

Again, make sure it works right, and document as you go along.

5. To turn in

Commit your changes to the repository. That's all that needs to be done.


Thomas VanDrunen
Last modified: Thu Jan 28 14:26:58 CST 2010