Thu Nov 7
1:00PM - 2:20PM
Type the answers to the written questions into the file
answers.txt
that you were instructed to create earlier.
Make sure that you number your answers to match the questions.
1. Consider the following main method:
public static void main(String[] args) { double radius = 1.0; Point2D center = new Point2D(2.0, -1.5); Shape s = new Circle(radius, center); boolean b = center == s.getPosition(); }
(a) [1 mark] If Shape
used aggregation for its field
named position
, what is the value
of the variable named b
?
true
, because center
and position
refer to the same object.
(b) [1 mark] If Shape
used aggregation for its field
named position
, how many Point2D
objects are (probably) created in the main method?
1
, because center
and position
refer to the same object.
(c) [1 mark] If Shape
used composition for its field
named position
, what is the value
of the variable named b
?
false
, because position
would be a deep copy
of center
(d) [1 mark] If Shape
used composition for its field
named position
, how many Point2D
objects are (probably) created in the main method?
3
: center
, position
, and
the copy created inside of getPosition
2. [2 marks]
Assume that Shape
is implemented correctly.
Does Shape
use aggregation or composition for
its field named position
? Explain your answer
(no marks for guessing aggregation or composition; you must
explain your answer).
The API for Shape
says that "The position of the
shape cannot be changed after the shape is created." The simplest
way that the class can ensure that the position not change
is if it uses composition because the field named position
is a mutable reference type.
3. [2 marks]
Suppose that Shape
used an IPoint2D
to represent position
instead of a Point2D
.
Could Shape
use aggregation for its position
without creating a privacy leak? Explain your answer.
(Recall that IPoint2D represents an immutable point.)
IPoint2D
is immutable; thus, aggregation could be used
without creating a privacy leak because immutable references can
be shared freely.
4. Imagine that you are teaching CSE1030. You provide the students with the following utility class:
public class Circles { // ... // returns a new Circle that is 2 times larger than c public static Circle doubleSize(Circle c) { return new Circle(2. * c.getRadius(), c.getPosition()); } // ... }
One of your students shows you their code:
// somewhere in a main method Shape c = new Circle(1., new Point2D()); // A Circle cc = Circles.doubleSize(c); // B
(a) [1 mark]
The student asks you what is the declared type of c
;
what is your answer to the student?
Shape
(b) [1 mark]
The student asks you what is the run-time (or actual) type of c
;
what is your answer to the student?
Circle
(c) [2 marks] The student asks you why is line A of the code shown correct; what is your answer to the student?
Circle
is a subclass of Shape
,
and is substitutable for Shape
; thus,
you can assign a
Circle
reference to a Shape
reference.
(d) [2 marks] The student asks you why is line B of code shown incorrect; what is your answer to the student?
The method doubleSize
has a Circle
reference as a parameter. The argument c
was
declared to be a Shape
reference, and a Shape
is not substitutable for a Circle
.
5. Suppose that Shape
had the following method:
/** * Changes the size of the shape so that its bounding box * has width w and height h. * * Precondition: w > 0 and h > 0 * * Postcondition: the width is set to w and the height is set to h * * @param w * the width of the shape's bounding box * @param h * the height of the shape's bounding box * */ public abstract void setSize(double w, double h);
(a) [2 marks]
The implementer of Circle
cannot satisfy the contract
of setSize
; explain why.
The bounding box for a Circle
is a square, and
it is impossible to independently set both the width and height
of a square.
(b) [1 mark]
Can the implementer of Circle
simply choose to not implement
setSize
? Explain your answer.
No, the method is marked abstract
and Circle
must implement all abstract methods of Shape
because
Circle
is a concrete class.
(c) Suppose that the implementer of Circle
overrides
setSize
as follows:
/** * Changes the size of the Circle so that its bounding box * has width equal to w. * * Precondition: w > 0 * * Postcondition: the width is set to w * * @param w * the width of the shape's bounding box * @param h * the height of the shape's bounding box (not used) * */ public void setSize(double w, double h) { // implementation not shown }
[2 marks] Is the change to the precondition acceptable? Explain your answer.
Yes, the precondition has been weakened, and a child class is allowed
to weaken a precondition on an overridden method. [Note: the precondition
is weakened because the requirement that h > 0
has
been removed.]
[2 marks] Is the change to the postcondition acceptable? Explain your answer.
No, the postcondition has been weakened, and a child class is not allowed
to weaken a postcondition on an overridden method. [Note: the postcondition
is weakened because the promise that the height is set to h
has
been removed.]
(d) Suppose that the implementer of Circle
overrides
setSize
as follows:
/** * This is an unsupported operation for circles. * * Precondition: none * * Postcondition: throws an Exception * * @param w * the width of the shape's bounding box * @param h * the height of the shape's bounding box (not used) * */ public void setSize(double w, double h) throws Exception { throw new UnsupportedOperationException(); }
[2 marks] Is throwing an exception acceptable? Explain your answer.
No, a child class cannot throw a checked exception in an overridden method if the parent class does not throw a checked exception in the overridden method.
(e) [2 marks]
The implementer of Line
also cannot satisfy the contract
of setSize
; explain why.
The API for Line
says that "The line end points cannot be
changed after the line is created" and it is impossible to change
the size of the bounding box without changing at least one of the line
end points.
Submit your answers to the written questions and your Java program when you are finished:
submit 1030 Test2 Circle.java Line.java answers.txt