How can I inherit from multiple common interface extensions?
I have several classes that:
public class XMLStatusMessage extends XMLMessage
{}
public abstract class XMLMessage implements IMessage
{}
public interface IMessageListener
{
public void onMessage( IMessage message );
}
public interface XMLMessageListener <T extends XMLMessage> extends
IMessageListener
{
public void onMessage( T message );
}
public interface XMLStatusMessageListener extends
XMLMessageListener <XMLStatusMessage>
{
@Override
public void onMessage( XMLStatusMessage message );
}
and
public class AStatusHandler implements XMLStatusMessageListener
{
//...
@Override
public void onMessage( XMLStatusMessage message )
{
//...
}
}
My problem is that AStatusHandler won't compile because I also don't implement public void onMessage (IMessage). I don't understand why I would have to implement onMessage (IMessage) as well, since it already implements onMessage (XMLStatusMessage) and XMLStatusMessage is IMessage. Is there a simple solution to this problem?
source to share
As the other answers indicate, you should be able to handle XMLStatusMessages in AStatusHandler, but I assume this is what you want? Update your interfaces as follows and I believe you will get what you want,
public interface IMessageListener<T extends IMessage> {
public void onMessage(T message);
}
public interface XMLMessageListener<T extends XMLMessage> extends IMessageListener<T> {
}
public interface XMLStatusMessageListener extends XMLMessageListener<XMLStatusMessage> {
}
Then you can create your message listener like this:
public class AStatusHandler implements XMLStatusMessageListener {
@Override
public void onMessage(final XMLStatusMessage message) {
// TODO Auto-generated method stub
}
}
Hope this is what you want and that it helps.
Relationship Bent
source to share
You are claiming (by injecting an IMessageListener) that you can call onMessage with any IMessage. What would you expect if you called:
new XMLMessageListener().onMessage(new SomeOtherMessage());
? If you think this should not be allowed, then you should not implement an IMessageListener.
source to share
I've been in these situations before, but there really isn't a perfect solution to this problem.
In your case, the IMessageListener defines an onMessage to receive the message.
Your XMLMessageListener that extends it defines onMessage to receive at least an XMLMessage.
Even if you ignored the generics, Java does not allow you to change the parameter type in the overridden version of the method. Thus, the two methods are considered overloads and your code will not compile because you have no definition for the version that receives the IMessage.
source to share
XMLStatusMessage is IMessage, but not vice versa. If there was another subclass of IMessage, say SMTPStatusMessage, then:
- onMessage (IMessage) can be passed to SMTPStatusMessage legally, but
- onMessage (XMLStatusMessage) failed.
If you don't expect anything other than XMLStatusMessage sent to AStatusHandler, then you can include onMessage (IMessage) IMessage in XMLStatusMessage and call onMessage (XMLStatusMessage), but that's not a very long strategy.
EDIT: Indeed, the question is, why is XMLMessageListener a subclass of IMessageListener at all, since presumably the classes calling onMessage (XMLStatusMessage) will never call onMessage (IMessage)?
source to share