JMU
Lab: Questions About Abstract Classes and Interfaces


Instructions: Answer as many of the following questions as you can during the lab period. If you are unable to complete the assignment during the lab period it is strongly recommended that you complete it on your own.

Getting Ready: Before going any further, you should:

  1. Make a directory for this lab.
  2. Setup your development environment.
  3. Download the following files:
    to the appropriate directory/directories. (In most browsers, the easiest way to do this is by right-clicking on each of the links above.)
  4. For a variety of reasons (that you will understand later in the semester), you will get a warning when you compile some of the classes that says something like:

      ... uses unchecked or unsafe operations.
      Note: Recompile with -Xlint:unchecked for details.
      

    You can and should just ignore this warning.

1. Basics: This part of the lab will help you determine whether you understand some of the basic issues involving abstract classes and interfaces.
  1. Familiarize yourself with the Comparator java.util.Comparator interface. (Note: For the time being, when you see a class with a one-letter name like T, you should assume that it is the Object class.)
  2. What methods are required of classes that implement the Comparator interface?

        public int compare(Object firstObject, Object secondObject)
        public boolean equals(Object other)
        

    Expand
  3. The DirectoryComparator class will compile without error even though it doesn't implement the equals(Object) method required by the Comparator interface. Why?
    There are actually two reasons. First, it inherits the method from the Object class. However, even if it didn't, it would compile because it is an abstract class and, as such, is not required to implement all of its methods (even those it "promises" to implement).
    Expand
  4. The DirectoryComparator class is abstract. What does that mean?
    You can't create instances of DirectoryComparator (i.e., you can't create objects that are members of the class DirectoryComparator).
    Expand
  5. What method(s) in the DirectoryComparator class must be implemented by concrete children?
    The compare(File, File) method must be implemented. The equals(Object) method needn't be implemented because it is inherited from the Object class.
    Expand
  6. DirectoryNameComparator extends DirectoryComparator. What method must it implement (in order to be concrete)?
    The compare(File, File) method (as discussed above).
    Expand
  7. Does the DirectoryNameComparator implement the Comparator interface?
    It does, but "indirectly" since it's parent implements the interface.
    Expand
  8. In the main() method of the DirectorySorter class, the variable comparatorToUse is declared to be a Comparator. Why is it possible to assign a DirectoryNameComparator or a DirectoryDateComparator to comparatorToUse?

    DirectoryNameComparator and DirectoryDateComparator implements the Comparator interface. Hence, for all intents and purposes, it behaves like it "is a" Comparator.

    Expand
  9. When the DirectorySorter is executed with no command-line arguments, the compare(Object, Object) message is sent to comparatorToUse by Arrays.sort(). Trace the methods that are executed as a result of this message. [Note: For each step, list the signature of the method that is called and the class it is in.]

        1.  compare(Object, Object) in DirectoryComparator
        2.  compare(File, File) in DirectoryNameComparator
        

    Expand
2. Design Issues: This part of the lab will help you determine whether you understand some of the issues involved in designing abstract classes and interfaces.
  1. What useful behavior/functionality do concrete children inherit from DirectoryComparator?
    The compare(Object, Object) method casts the parameters as File objects and calls the compare(File, File) method.
    Expand
  2. Why does it make sense to have an abstract DirectoryComparator class? In other words, why shouldn't we just include the compare(Object, Object) method in the DirectoryDateComparator class?
    Because we might have other ways of comparing directories (e.g., based on size) that could use the compare(Object, Object) method in the DirectoryComparator class.
    Expand
  3. The DirectorySorter class contains a containsSwitch method. Why must this method be static?

    It is called from the main() method which is static. (Since main() is static, it can be executed even if a DirectorySorter object does not exist. Hence, all methods and attributes it uses must also be static.)

    Expand
  4. Draw a UML class diagram that shows the relationship between java.lang.Comparator, DirectoryComparator, DirectoryDateComparator, DirectoryNameComparator, and java.lang.Object. (NOTE: You do not have to submit your answer to this question.)

    overview.gif

    Expand
3. More Design Issues: This part of the lab will help you determine whether you understand some of the issues involved in designing systems that have abstract classes and interfaces.
  1. Some of the classes and interfaces from previous labs are summarized in the following UML class diagram:

    AbstractClassesAndInterfaces.png

    Familiarize yourself with (or refresh your memory about) these classes and interfaces. (Note: In UML, abstract methods/classes are denoted by slanted text, specialization is denoted by an arrow with a solid line, and realization/implementation of an interface is denoted by an arrow with a dashed line.)

  2. Why is it a good idea to include the TwoPartNumber class in this design? In other words, what would be bad about omitting the abstract TwoPartNumber class?
    It implements methods that are needed in both of its subclasses, Length and Weight. If it were omitted, those two classes would contain duplicate code.
    Expand
  3. Concrete subclasses of TwoPartNumber must have an initializeUnits() method. What must be done in this method?
    The units for the small and large components must be initialized and smallsPerLarge must be initialized.
    Expand
  4. Why is this abstract method included in TwoPartNumber (rather than, for example, simply including a comment that says all subclasses must have such a method)?
    There are two reasons. First, by including it as an abstract method the compiler can check to ensure if the method has been included in concrete subclasses. Second, the initializeUnits() method is called in the TwoPartNumber class' constructor.
    Expand
  5. Syntactically, why must the TwoPartNumber class be declared abstract?
    Because it has an abstract method.
    Expand
  6. Conceptually, why should the TwoPartNumber class be declared abstract?
    It doesn't make sense to have TwoPartNumber objects. Length and Weight objects correspond to real-world entities/concepts but TwoPartNumber objects do not.
    Expand
  7. Why is it a good idea to include the Comparable interface in this design?
    It allows us to identify which objects can be compared and, hence, whether an array of a particular kind of objects can be sorted.
    Expand
  8. In this design, how are TwoPartNumber and HolidayAccount related?
    They are only related indirectly. That is, they are both Comparable.
    Expand
  9. Why doesn't it make sense to have HolidayAccount extend TwoPartNumber?
    Because there is no sense in which a HolidayAccount "is a" TwoPartNumber. They have no attributes in common and the only method they have in common is compareTo() (and, perhaps, toString()).
    Expand

Copyright 2015