CS210 Thurs., Jan. 26

Handout

Also note that hw1 is online, linked to the class home page, www.cs.umb.edu/cs210

Coming soon: pa1, first programming assignment.

First Topic: Advanced Objects

Chap 3 of Weiss:

mutators and accessors—look at class Date (in handout)

Use simple objects like this whenever possible, but we do need some more advanced features for some cases.

Ticket class, pg. 76, shows static field ticketCount. This memory cell is associated with the  “class object” of class Ticket, while each Ticket object has a memory cell with serialNumber in it.

Chap 4

Class Person vs. Class Student

Look at class Person, Student, pp. 95-96.  See 4 fields same in both, one more field in Student.  Already thinking about inheritance to replace this parallel fields setup, but there’s a test to go through first, the “IS-A” test.  Need to feel sure that we can say “A Student IS-A Person”.  OK, that makes sense, so we set up inheritance between them, as shown on pg. 97.

There is an additional field in Student, gpa.  So a Student IS-A Person, with a gpa.  It’s normal to have additional attributes in subclasses like this.

Note the picture on pg. 97, showing how the Student object has the Person fields as well as gpa, but the shading indicates that they are hidden from the code of class Student because they are private to Person.  Here the code of Student can call the public methods of Person and get all the info on an already-existent Person object. 

The constructor needs special syntax, shown on pg. 103, super(n, ag, ad, p).  This calls the constructor of the superclass, here Person.  The Student constructor goes on to initialize the gpa field as well.  The keyword “super” is also used to disambiguate calls to methods that show up in both the sub and superclass, as shown on pg. 105.

Note the example on pg. 100 showing how a Person reference p can refer to either a Person or an Employee object based on some criterion.  We can later tell which it is by using instanceOf.  This is shown on pg. 107 (end of page.)

The Shape class hierarchy: various shapes have various area formulas

Look at the Shape class hierarchy on pp. 109.  Here we are involved with various shapes, and each has its own area formula.  

The goal is to be able to add up areas of an array of objects representing various shapes.

What we need to do is design a hierarchy with common behavior in the base class, separate details in the derived classes.  Do IS-A check:

A Circle IS-A Shape

A Rectangle IS-A Shape

A Square IS-A Rectangle

 and the IS-A check passes, so we get the hierarchy shown on pg. 109.

First this is set up with the simplest possible inheritance structure (pg 111-112), with an ordinary Shape class as base class, and Circle extends Shape, and Rectangle extends Shape, and Square extends Rectangle.  

See how all classes but Square have method area.  Square just uses the area method it gets for free from Rectangle, since it works fine.

Note the area method in class Shape.  Here we want an area method so that Shape objects can support calls to area, since that is part of our goal.

But a Shape (pg. 110) doesn’t know how to calculate its area!  So the “placeholder” approach returns -1 as the clearly-wrong area value, with the hope that if anyone ever sees this funny value, they will know there’s a bug and do something about it.  Another programmer would use an exception.  The system works fine as long as all subclasses actually override area and provide a correct area formula.

The Shape class as an abstract class

This placeholder approach works fine but there is a more advanced way to express this thought that:

Every Shape has an area (it can be calculated in various ways for various shapes.)

We make the area method abstract in Shape.  That means it has no code in Shape, but must have code for area in each subclass (or subclass’s subclass, etc.).  We are explicitly “passing the buck” on how to calculate area to the various subclasses.  Once we’ve made any method of a class abstract, the whole class must be abstract.  See pg. 113.

While we’re at it, we note that every shape has a perimeter, and semiperimeter (half its perimeter.)  These have been added to the class definition on pg. 113.  Note how we can actually implement semiperimeter here in the abstract class.  Abstract classes are allowed to have code, and fields and constants too.  They are just classes with at least one abstract method.  As seen on pg. 114, you can’t use “new Shape()” because it’s an abstract class—it would not know how to calculate its area.

Note that although an abstract class can’t be instantiated (via new), we can put:

Shape a;       // This just defines an object ref, not an object 

but not this: 

a = new Shape();   // Illegal: Shape is an abstract class

Instead, we apply new to Circle, Rectangle, or some other concrete subclass:

a = new Circle(3.0);    // a Circle IS-A Shape, so this passes type match test
 

Idea of an API, applications programming interface

An API is a collection of related function specifications and constants to go with them, where the function specs only tell the name, return type, and argument types, that is the function's "signature."  These functions can be called from outside the code that implements them, and thus form the definition of the services this code can provide to other code. This is a language-neutral definition that applies to C, C++, C#, and any other modern programming language.

Example:  we talk about the API of the standard C library, with calls like int fopen(char *name, char *mode).

In Java, each class has an API consisting of its public method signatures and public constants (public final fields.)  

To see other ways of defining API, do a Google search for "define API".

With an abstract class, the public abstract methods can be called "pure API" because they don't have any code in this class.  Of course an abstract class can have implemented methods too, so the full API of an abstract class has the public abstract methods plus the other public methods, plus the public constants, in other words the API as originally defined for a class.

Now we’ll look at interfaces, which are the purest form of abstract class—no code, no fields, just abstract methods and constants.  Very lightweight—just ideas, not how to do them.  Perfect for describing APIs.

Interfaces:  abstract classes  that are pure API.

Interfaces are very helpful for description of what classes can do.  For example, ArrayList is a class that implements Collection and List—we’ll be studying these interfaces.  For Collection, see pg. 192 in Weiss or look it up in your IDE help (try this out.)  Anything that implements Collection must provide all the methods listed: size, isEmpty, …  Thus we know quite a bit about ArrayList just from this quick description.

See example in class handout (not in Weiss) of interface for Shape, called AShape here to differentiate it in our discussion.

Since an interface is the extreme form of an abstract class, it has all the restrictions of an abstract class--you can't use it with new.  

But you can use object ref's of interface type, referencing objects whose classes implement the interface--very powerful technique we'll be using all the time.

:Let's replace the abstract class Shape with interface AShape, convert code on pg. 111--
public class Circle implements AShape ...
public class Rectangle implements AShape...
public class Square extends Rectangle (same as before)

Now we can say a "Circle ISA AShape", etc., treating AShape as an abstract class. We can put

    AShape a;       // This just defines an object ref, not an object 

but not this: 

    a = new AShape();   // Illegal: Shape is an interface, so an abstract class

Instead, we apply new to Circle, Rectangle, or some other concrete class that implements AShape:

    a = new Circle(3.0);    // a Circle ISA AShape, so this passes type match test

Study example of Comparable in book.  We’ll see Collection, Iterator, Map, …pretty soon.

Study Weiss through Chap 4 for now, can skip 4.5.3 (i/o) and 4.8, 4.9.  We'll come back to it when needed.

Errata: pg. 136, remove 2 from "Object list2 = list1;"