(Brief) Notes on Chapters 9-12 and 15

Chapter 9 - Solitaire Game Case Study

Note use of inheritance:
  Object
    Card
    CardPile
      SuitePile
      DeckPile
      DiscardPile
      TablePile
CardPile has methods such as select, pop, and canTake. select and canTake are overridden by various subclasses - but common behavior is factored into CardPile.

Use of private fields with methods for access - prevents tampering with the field from outside the object (e.g. rank, suite, faceup inside of Card).

Use of final modifier to indicate methods that cannot be overriden in subclasses. (Some controversy about the merits of this.)

Chapter 10 - Mechanisms for Software Reuse

Composition and inheritance (is-a and has-a relation).

Novel forms of composition - field that holds a different kind of part depending on the object's state. (This is the "state" pattern.) Example in book: Frog with a behavior field, which holds either tadpole or adult. Other examples: window object, which holds either a full window or an iconified window; mutable list object, which holds either an empty list or a nonempty list.

Anonymous classes

Chapter 11 - Implications of Inheritance

Memory layout: stack vs heap - see p 178. We talked about this earlier - questions?

For objects in Java, assignment copies a reference to the object, but doesn't copy the object. This is also true for passing objects as parameters. (This is the same as in Scheme, when we passed lists as parameters or assigned them to variables.)

Chapter 12 - Polymorphism

Polymorphic: from the Greek - "many forms". Another important use: Red Dwarf episode Polymorph.

"Polymorphic" has a precise meaning in the functional programming community, and we'll study this next in the context of Miranda.

There is unfortunately less agreement in the programming language community at large on the meaning of "polymorphic". We'll adopt the book's definition for object-oriented languages.

A polymorphic function (or method) is one that can be applied to a variety of types. Examples: object.equals(x) -- x can be any type of object.

target.hitBy(b) ... target can be any subclass of PinBallTarget.

Polymorphic variables can hold objects of different classes. Object-oriented languages support bounded polymorphism -- often the variable can't hold just any object, but only objects that are instances of a given class or its subclasses.

Overloading: a function name is overloaded if there are two or more function bodies associated with that name, and we choose the body based on the types of the arguments. Example: + in C.

i+j for integers i and j vs. x+y for floats x and y

Coercion - a separate concept from overloading. Consider i+x for integer i and float x -- we coerce i to float (and use the + for floats).

Another technique: templates (or generics), as in the C++ Standard Template Library. In C++ one can declare a class parameterized with a type T. C++ generates multiple copies of the class for each type of parameter. (Note that this is essential if variables of type T are stored on the stack, since different actual types for T may require different amounts of storage. This isn't an issue in Java since all objects are stored on the heap.)

There are a number of proposals to add a facility for parameterized classes to Java, so that one can for example declare a variable such as

   Vector<PinBallTarget> targets = new Vector();
Then we can write statements such as
   PinBallTarget t;
   t = targets.elementAt(1);
rather than
   t = (PinBallTarget) targets.elementAt(1);
None of these proposals (as far as I know) use C++ style templates -- rather, there would still be a single class Vector. But we would know at compile time that it held PinBallTargets.

Chapter 15 - Design Patterns

This chapter describes a number of patterns in the Java library, using terminology from the well-known book Design Patterns.

A few examples: