CSE 331: Section 6 — Subtyping
Task 1 – A Square and a Rectangle Walk Into a bar()...
Consider the following classes.
public class Rectangle {
private int width;
private int height;
public int getWidth() { ... }
public int getHeight() { ... }
// @effects this.width = w
public void setWidth(int w) { ... }
// @effects this.height = h
public void setHeight(int h) { ... }
}
public class Square {
private int side;
public int getWidth() { ... }
public int getHeight() { ... }
// @effects this.side = w
public void setWidth(int w) { ... }
// @effects this.side = h
public void setHeight(int h) { ... }
}
public class ImmutableRectangle {
private int width;
private int height;
public int getWidth() { ... }
public int getHeight() { ... }
}
public class ImmutableSquare {
private int side;
public int getWidth() { ... }
public int getHeight() { ... }
}
For each comparison below, answer Yes or No and briefly justify your answer.
| Comparison | Yes / No |
|---|---|
Is Square a behavioral subtype of Rectangle? | |
| Why or why not? | |
Is Rectangle a behavioral subtype of ImmutableRectangle? | |
| Why or why not? | |
Is ImmutableSquare a behavioral subtype of ImmutableRectangle? | |
| Why or why not? | |
Is ImmutableRectangle a behavioral subtype of Rectangle? | |
| Why or why not? | |
Task 2 - Thing 1 and Thing 2
Consider the following class Thing:
class Thing {
private int contents;
public Thing(int value) { this.contents = value; }
public boolean equals(Thing other) { return this.contents == other.contents; }
}
Unfortunately Thing does not correctly override equals, but overloads it
instead. As a result, there are two methods called equals, but with different
signatures: equals(Object) and equals(Thing).
Here is a program that uses class Thing.
public static void main(String[] args) {
Thing t = new Thing(17);
Object o = t;
Thing u = new Thing(17);
System.out.println(t.equals(o));
System.out.println(t.equals(u));
System.out.println(o.equals(u));
System.out.println(u.equals(o));
System.out.println(u.equals((Thing) o));
}
For each System.out.println statement, indicate which equals method is
called (equals(Object) or equals(Thing)), and whether the statement prints
true or false. Check one box in each group.
| Expression | Which method is called? | What is printed? | ||
|---|---|---|---|---|
equals(Object) |
equals(Thing) |
true |
false |
|
t.equals(o) |
||||
t.equals(u) |
||||
o.equals(u) |
||||
u.equals(o) |
||||
u.equals((Thing) o) |
||||
Task 3 - Wrecked Angle
Here is a small class with a correctly overridden equals method.
public class ColoredRectangle {
private int width; private int height; private String color;
/** equality for ColoredRectangles. Two ColoredRectangles
* are the same if they have the same width and height. */
@Override
public boolean equals(Object o) {
if (! (o instanceof ColoredRectangle)) {
return false;
}
ColoredRectangle cr = (ColoredRectangle) o;
return this.width == cr.width && this.height == cr.height;
}
}
Below are five possible hashCode functions for ColoredRectangle. For each one indicate if it is incorrect
(does not satisfy the specification for hashCode), or if it is correct but very poor, or correct
and adequate-to-good. Check one box for each.
(Hints: ^ is the exclusive-or arithmetic operation. Recall that if a.equals(b) is true, then
a.hashCode() must equal b.hashCode().)
-
public int hashCode() { return width; }Not correct Correct but very poor Correct and adequate-to-good -
public int hashCode() { return color.hashCode(); }Not correct Correct but very poor Correct and adequate-to-good -
public int hashCode() { return 42; }Not correct Correct but very poor Correct and adequate-to-good -
public int hashCode() { return width ^ height ^ color.hashCode(); }Not correct Correct but very poor Correct and adequate-to-good -
public int hashCode() { return width ^ height; }Not correct Correct but very poor Correct and adequate-to-good