Как мне наследовать от нескольких расширяющихся универсальных интерфейсов? - PullRequest
0 голосов
/ 06 января 2009

У меня есть несколько классов, таких как:

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 );
}

и

public class AStatusHandler implements XMLStatusMessageListener
{
    //...
    @Override
    public void onMessage( XMLStatusMessage message )
    {
        //...
    }
}

Моя проблема в том, что AStatusHandler не будет компилироваться, потому что я также не реализую публичный void onMessage (IMessage). Я не понимаю, почему мне нужно реализовать onMessage (IMessage) также, поскольку он уже реализует onMessage (XMLStatusMessage), а XMLStatusMessage - это IMessage. Есть ли простое решение этой проблемы?

Ответы [ 4 ]

2 голосов
/ 07 января 2009

Как указывают другие ответы, вы сможете обрабатывать только сообщения XMLStatusMessage в AStatusHandler, но я думаю, что это то, что вы хотите? Переименуйте ваши интерфейсы следующим образом, и я верю, что вы получите то, что хотите;

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> {
}

Затем вы можете создать прослушиватель сообщений следующим образом;

public class AStatusHandler implements XMLStatusMessageListener {

    @Override
    public void onMessage(final XMLStatusMessage message) {

        // TODO Auto-generated method stub

    }

}

Надеюсь, это то, что вы хотите, и это помогает.

С уважением Бент

1 голос
/ 06 января 2009

Вы утверждаете (реализуя IMessageListener), что вы можете вызывать onMessage с любым IMessage. Что бы вы ожидали, если бы вы позвонили:

new XMLMessageListener().onMessage(new SomeOtherMessage());

? Если вы думаете, что это не должно быть разрешено, вы не должны реализовывать IMessageListener.

0 голосов
/ 06 января 2009

XMLStatusMessage - это IMessage, но не наоборот. Если был другой подкласс IMessage, скажем, SMTPStatusMessage, то:

  1. onMessage (IMessage) может быть передано SMTPStatusMessage законно, но
  2. onMessage (XMLStatusMessage) не удалось.

Если вы не ожидаете, что что-то кроме XMLStatusMessage будет отправлено в AStatusHandler, тогда вы можете сделать так, чтобы onMessage (IMessage) приводил IMessage к XMLStatusMessage и вызывал onMessage (XMLStatusMessage), но это не очень хорошая долгосрочная стратегия.

EDIT: Действительно, вопрос в том, почему XMLMessageListener вообще является подклассом IMessageListener, поскольку предположительно классы, вызывающие onMessage (XMLStatusMessage), никогда не будут вызывать onMessage (IMessage)?

0 голосов
/ 06 января 2009

Я был в таких ситуациях раньше, но на самом деле не существует прекрасного решения этой проблемы.

В вашем случае IMessageListener определяет onMessage для получения IMessage.

Ваш XMLMessageListener, который расширяет его, определяет onMessage для получения как минимум XMLMessage.

Даже если вы игнорировали обобщенные значения, Java не позволяет вам изменять тип параметра в переопределяющей версии метода. Таким образом, оба метода считаются перегрузкой, и ваш код не будет компилироваться, поскольку у вас нет определения для версии, которая получает сообщение IMessage.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...