Given:
interface Printable<E> { void print(E x); } abstract class Shape {} interface TwoDimension<E extends Shape> extends Printable<E> {} interface ThreeDimension<E extends Plant> extends Printable<E> {} abstract class Plant {} class Grass extends Plant {} class Cube extends Shape implements ThreeDimension<Cube> { public void print(Cube x) {} } class Square extends Shape implements TwoDimension<Cube> { public void print(Cube x) {} }
Which of the following changes (taken separately) would allow this code to compile?
Choose all that apply.
A. Change the TwoDimension interface to interface TwoDimension<E extends Plant> extends Printable<E> {} B. Change the ThreeDimension interface to interface ThreeDimension<E extends Shape> extends Printable<E> {} C. Change the Cube class to class Cube extends Shape implements ThreeDimension<Plant> { public void print(Grass x) {} }/*from ww w . ja va 2s . c o m*/ D. Change the Cube class to class Cube extends Plant implements TwoDimension<Square> { public void print(Square x) {} } E. Change the Square class to class Square extends Shape implements ThreeDimension<Grass> { public void print(Grass x) {} } F. No changes are necessary
B is correct.
The problem with the original code is that Cube tries to implement ThreeDimension<Cube>
and ThreeDimension
declares that its type parameter E can be any type that extends Plant.
Since a Cube is not a Plant, ThreeDimension<Cube>
makes no sense-the type Cube is outside the allowed range of ThreeDimension's
parameter E.
Only solutions that either alter the definition of a Cube or alter the definition of ThreeDimension
will be able to fix this.
So A, E, and F are eliminated.
B works-changing the definition of an ThreeDimension
to allow it to eat Cube solves the problem.
C doesn't work because an ThreeDimension<Plant>
must have a print(Plant) method, not print (Grass).
And D doesn't work, because in D we made Cube extend Plant-now the Square class breaks because its print(Cube) method no longer fulfills the contract of TwoDimension
.