wood burning stoves 2.0*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes puzzled by this question Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "puzzled by this question" Watch "puzzled by this question" New topic
Author

puzzled by this question

Lei Szymanski
Greenhorn

Joined: Oct 24, 2007
Posts: 1
One page 628 of the Java 5 study guide:

interface Hungry<E> { void munch(E x); }
interface Carnivore<E extends Animal> extends Hungry<E> {}
interface Herbivore<E extends Plant> extends Hungry<E> {}
abstract class Plant {}
class Grass extends Plant {}
abstract class Animal {}
class Sheep extends Animal implements Herbivore<Sheep> {
public void munch(Sheep x) {}
}
class Wolf extends Animal implements Carnivore<Sheep> {
public void much(Sheep x) {}
}

Why wouldn't the following change work?
D. Change the Sheep class to
class Sheep extends Plant implements Carnivore<Wolf> {
public void munch(Wolf x) {}
}

Thanks.
Jari Timonen
Ranch Hand

Joined: Jan 16, 2004
Posts: 230
Question:

Which of the following changes (taken separately) would allow this code to compile?
(Choose all that apply.)
A. Change the Carnivore interface to
interface Carnivore<E extends Plant> extends Hungry<E> {}
B. Change the Herbivore interface to
interface Herbivore<E extends Animal> extends Hungry<E> {}
C. Change the Sheep class to
class Sheep extends Animal implements Herbivore<Plant> {
public void munch(Grass x) {}
}
D. Change the Sheep class to
class Sheep extends Plant implements Carnivore<Wolf> {
public void munch(Wolf x) {}
}
E. Change the Wolf class to
class Wolf extends Animal implements Herbivore<Grass> {
public void munch(Grass x) {}
}
F. No changes are necessary.



Answer:

B is correct. The problem with the original code is that Sheep tries to implement
Herbivore<Sheep> and Herbivore declares that its type parameter E can be any type that
extends Plant. Since a Sheep is not a Plant, Herbivore<Sheep> makes no sense´┐Ż
the type Sheep is outside the allowed range of Herbivore's parameter E. Only solutions that
either alter the definition of a Sheep or alter the definition of Herbivore will be able to fix
this. So A, E, and F are eliminated. B works, changing the definition of an Herbivore to
allow it to eat Sheep solves the problem. C doesn't work because an Herbivore<Plant>
must have a munch(Plant) method, not munch(Grass). And D doesn't work, because
in D we made Sheep extend Plant, now the Wolf class breaks because its munch(Sheep)
method no longer fulfills the contract of Carnivore. (Objective 6.4)


So, when you make sheep correct you brake wolf (since wolf is eating Sheep, and agreement says: <E extends Animal> NOT <e extends Plant> )
[ October 24, 2007: Message edited by: Jari Timonen ]

SCJP 5.0, SCJD URLyBird 1.3.3, OCMJEA 5 (SCEA) Factory Homes
adam Lui
Ranch Hand

Joined: Sep 03, 2007
Posts: 186
May i ask why C cant make the answer.

the answer explained :
"C doesnt work because an Herbivore<Plant> must have a munch(Plant) method, not munch Grass."

ok, we sub Plant into the E placeholder in the code.
[code]
interface Hungry<Plant> { void munch(Plant x); }-- change made, line 1, my doubt here
interface Carnivore<E extends Animal> extends Hungry<E> {}
interface Herbivore<Plant extends Plant> extends Hungry<E> {}-- change made
abstract class Plant {}
class Grass extends Plant {}
abstract class Animal {}
class Sheep extends Animal implements Herbivore<Plant> {-- change made
public void munch(Grass x) {} -- change made
}
class Wolf extends Animal implements Carnivore<Sheep> {
public void much(Sheep x) {}
}

i could be wrong. According the book, subtypes can take effect in generics, so Grass is a subclass, or an instanceof of Plant, so at line 1 should be fine. i.e.
in Hungry interface
public void munch(Plant x) {}
in sheep class, which implements Hungry
public void munch(Grass x) {}


or this is illegal as an OO rule?


boolean b = true;<br />System.out.println ("I believe in Java.<br />Java will make my dream come " + b);
Kelvin Chenhao Lim
Ranch Hand

Joined: Oct 20, 2007
Posts: 513
Originally posted by adam Lui:
i could be wrong. According the book, subtypes can take effect in generics, so Grass is a subclass, or an instanceof of Plant, so at line 1 should be fine. i.e.
in Hungry interface
public void munch(Plant x) {}
in sheep class, which implements Hungry
public void munch(Grass x) {}

Hi Adam,

You should think of an interface method as basically an abstract method that you must override in a concrete class. To override a method, you must provide an implementation that has exactly the same signature (i.e. same method name and parameter types). If you change the parameter types, you're overloading the method, not overriding it, so that's not enough to fulfill the contract of the interface.

While it's true that you can change the method's return type to a covariant type, this doesn't apply to the parameter types.


SCJP 5.0
adam Lui
Ranch Hand

Joined: Sep 03, 2007
Posts: 186
THANKS Kelvin
Karen Marie
Greenhorn

Joined: Nov 10, 2007
Posts: 23
The explanation of why C doesn't work was very helpful. Thanks.

I'm still unclear on how D breaks the contract of Carnivore. Something isn't clicking in to place.
Karen Marie
Greenhorn

Joined: Nov 10, 2007
Posts: 23
Nevermind. It clicked.

Sheep extends Plant means that now Sheep IS-A Plant. Carnivore<E extends Animal> means the generic type of Carnivore must be Animal or something that extends Animal.

So while D compiles fine in the originally broken line:
class Sheep extends Plant implements Carnivore<Wolf>{
public void munch(Wolf x){ }
}

...it now breaks the line that previously compiled...:
class Wolf extends Animals implements Carnivore<Sheep>{
public void munch(Sheep x){ }
}

...since Sheep no longer extends Animal.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: puzzled by this question
 
Similar Threads
Generic Types extending Abstract implementing Interface
page# 616 question# 10
K&B -From genric & collections-Self Test
K&B collection and generic question
Generics