CS 2102 - B-term 08

Homework 6 - Abstracting over Behavior

Due: Tuesday, December 9 at 11:59pm

Acknowledgements

This assignment is a modified version of an assignment designed by Felleisen, Proulx, et al., 2008

Assignment Goals


Assignment

We have seen that a class can implement several interfaces, each defining methods that the class has to implement. In the past we have written methods that determined whether all or some items in a list satisfy some condition. We had to duplicate much code in order to specify the particular condition over the particular kind of data stored in the list. In this homework, we will design a hierarchy that allows us not only to abstract over the data, but to abstract over the behavior as well.

Problems

  1. From HW6.zip, download the files

    Create a new project under Eclipse containing all these files and run the project.

  2. The method contains() determines whether the list of data items contains one specific data item, using the same-ness criterion defined in the method that implements the ISame interface. We would like to generalize this behavior to see if the list contains any item that satisfies a broader criterion.

    Define the interface Selectable as follows:

    // to represent a method for selecting items
    interface Selectable{
      boolean isOK();
    }
    
    Add this interface to your project in a file called Selectable.java.

    In the class Book implement this interface so it selects all books published before 1950.

    In the class Acct implement this interface so that it selects all accounts with a balance below $2500.

    Define the method countSuch() that counts the number of items in a list that satisfies the criterion specified by the isOK() method. Provide tests for the method.

  3. In CS 1101/1102, some of you may have seen the functions andmap and ormap. andmap determines whether all items in a list satisfy some criterion, and ormap determines whether at least one item in a list satisfies some criterion. The (DrScheme) contracts for these functions are as follows:
    ;; andmap:  (X -> boolean) list-of-X -> boolean
    ;; determines whether p holds for every item in aloX
    ;; that is, (andmap p (list x1 x2...xn)) =
    ;;          (and (p x1) (and ... (p xn)))
    (define (andmap p aloX)...)
    
    ;; ormap:  (X -> boolean list-of-X -> boolean
    ;; determines whether p holds for at least one item in aloX
    ;; that is, (ormap p (list x1 x2...xn)) =
    ;;          (or (p x1) (or ... (p xn)))
    (define (ormap p aloX)...)
    
    You can see that each function consumes not only the list of items, but also a function for determining whether or not each item should be selected. In DrScheme, functions can be passed as parameters. C supports function pointers which provide a similar capability. Function pointers were removed from the Java programming language, but object references can be used to provide the same functionality. We'll examine the use of function objects here.

    Let's start by seeing how far the Selectable interface takes us. If we know that a list contains instances of a class that implements the Selectable interface, we can use the method isOK() to check whether any of the items satisfy the desired condition. However, this is not enough. We may want to check if all books are published before 1950; but another time we may want to check if any of the books were written by a specific author, in effect changing the implementation for isOK(). We need to be able to define several different methods that determine whether or not a book is OK.

    Instead of the Selectable interface, let's define an interface parameterized over the type T, that can be implemented outside of any class. The interface will specify a method choose() that consumes an item of type T and returns true or false as appropriate:

    // to represent a METHOD that specifies a selection criterion
    interface Selector<T>{
    
    // determine whether the given item should be selected
    boolean choose(T t);
    }
    
    Add this interface to your project in a file named Selector.java

    Define a class named BookBefore1950 that implements Selector to choose books published before 1950. Add this class to your project. In the Examples class, define an instance of BookBefore1950. Design tests for the method choose() as implemented by BookBefore1950.

  4. You could use the same design as you did in Problem 3 to select BookWrittenByHemingway, or BookWrittenByMF. But we can go further. The name of the author can be defined as a field and provided to the constructor. Complete the definition of the following class and add it to your project:
    // to represent a boolean method that selects books by the given author
    class BookWrittenBy implements Selector<Book>{
        String authorName;
    
        // you provide the constructor
    
    
    
        // you provide the implementation for choose()
        // was the given book written by authorName?
    
    
    }
    
    In the Examples class define an instance of BookWrittenBy that selects books written by Hemingway. Design tests.

    Design the class AcctOwnedBy that implements the interface with a method that determines whether an account is owned by an owner with a specified name. Provide examples and tests.

    The Comparator interface in the package java.util is defined like this.

  5. Design the method orMap() that determines whether or not a list contains at least one item that satisfies the given condition. Run tests for both lists of books and lists of accounts.

  6. Design the method andMap() that determines whether or not every item in a list satisfies the given condition. Run tests for both kinds of lists.

What to turn in

Using web-based turnin, turn in a single file hw6.username.zip containing all code and documentation for this assignment. Both partners' names and wpi login names should appear in a comment at the top of each file.