CSE1030

Lab 5 Written Solutions

Tue Oct 22 and Thu Oct 24
Due: Mon Oct 28 before 11:59PM

Written Questions

The following are some written questions about inheritance based on the lab; you do not need to submit answers to these questions.

  1. Do both appply and transform need to be abstract in Transformation? Explain your answer.
  2. All of the transformations discussed in this lab including translation can be represented using a real 3x3 matrix. The matrix representation is convenient because a series of transformations applied one after another can be computed using matrix multiplication. Suppose that you wanted to add a field to represent the matrix for a transformation; in which class should the field be defined?
  3. Should the method getMatrix be declared abstract in Transformation?
  4. The transformations that can be represented using a 3x3 matrix (where the third row of the matrix is 0 0 1) are called affine transformations. There are many other transformations that are not affine transformations, but still support the API provided by Transformation. Suppose that you want to design an inheritance hierarchy that represents affine transformations and all other transformations that support the Transformation API. Draw the UML diagram showing your inheritance hierarchy.

Solutions

1. No, only one of the methods needs to be abstract because the other method can be implemented in terms of the abstract method. For example, if you make transform abstract, then the child classes must implement transform. The method apply could then be moved into Transformation and implemented like so:

public Point2D apply(Point2D p) {
  Point2D q = new Point2D(p);       // make a copy of p
  this.transform(q);                // transform the copy changing its coordinates
  return q;                         // return the transformed copy
}

Notice that apply uses none of the fields in the child, and transform is overridden by the child, so placing it in Transformation works just fine.

If you make apply abstract, then the child classes must implement apply. The method transform could then be moved into Transformation and implemented like so:

public void transform(Point2D p) {
  Point2D q = this.apply(p);        // apply the transformation to p to get q
  p.setX(q.getX());                 // set the coordinates of p to those of q
  p.setY(q.getY());
}

2. Because all of the transformations in the lab can be represented using a real 3x3 matrix, the matrix should be defined in the Transformation base class. The child classes would be responsible for setting the matrix elements.

3. No, getMatrix should not be declared abstract in Transformation because Transformation can implement getMatrix if one of its fields is the matrix. For example:

public abstract class Transformation {

  private double[][] matrix;  // we could use a 2D array to store the matrix
  
  // ...
  
  public double[][] getMatrix() {
    return this.matrix;
  }
  
  // ...
}

4. This is one possibility:

However, affine transformations have the property that any sequence of affine transformations is also an affine transformation; e.g., a scale followed by a rotation followed by a shear is also an affine transformation that can be represented as a 3x3 matrix. Therefore, it makes sense that someone would want to create such a transformation object, so AffineTransformation should not be abstract.