2016-08-17 3 views
1

У меня есть этот Java код:Реализовать метод с параметром расширенного интерфейса

public interface User{ 
    public void in(Message message); 
} 

public interface Message{ 
//.... 
} 

public interface WebsiteMessage extends Message{ 
//.... 
} 

public class WesiteUser implements User{ 
    @Override 
    //I'm not allowed to do this 
    public void in(WebsiteMessage message){} 
} 

Есть ли способ я могу реализовать in метод с параметром WebsiteMessage? На данный момент я делаю что-то вроде этого:

@Override 
public void in(Message message){ 
    WebsiteMessage msg= (WebsiteMessage) message; 
    //.. 
} 
+5

Разрешено ли вам изменять «Пользователь»? – Spotted

+0

@ Исправлено да. Я уже выбрал ответ. Но вы можете предоставить его, если я не могу изменить пользователя, и я буду его голосовать. –

+0

Если вы не можете изменить 'User', я не вижу простого решения. Тем не менее, я думаю, что ваш текущий дизайн испорчен, если вам нужно «WebsiteMessage» (вместо «Message») в «WebsiteUser». Это указывает на то, что ваш интерфейс протекает, и я начну с обработки 'Message', чтобы каждая реализация' User' могла работать с 'Message'. – Spotted

ответ

5

Вы можете сделать это с bounded type parameter:

public interface User<M extends Message> { 
    public void in(M message); 
} 

public class WebsiteUser implements User<WebsiteMessage> { 
    @Override 
    public void in(WebsiteMessage message) {} 
} 
+1

Это ответ, о котором я думал, но только выполнимый, если «Пользователь» может быть изменен, как кто-то спросил в комментариях. –

+0

@ RayO'Kalahjan Ну, конечно, но я не вижу никаких признаков в вопросе, что этого не может быть. – shmosel

+0

Конечно, я только что упомянул об этом, потому что я видел вопрос в комментариях. Это единственный правильный ответ, о котором я могу думать. –

3

Просто чтобы дать другой перспективе: Liskov Substitution Principle в основном говорит вам ... к не делайте этого.

Идея этого принципа заключается в том, что для того, чтобы быть здоровым, вы должны иметь возможность заменить любое использование «базового» типа «производным» типом. И это не работает, если вы ограничиваете параметры методов. Потому что при вызове метода в базовом классе вам разрешается использовать «более широкий» тип; который дает вам ошибку при попытке использовать производный класс.

Прекрасно ограничивать тип возврата; или для расширения параметров метода; но не наоборот.

И если вы включите here, вы обнаружите, что люди спорят, применяется ли LSP, когда речь идет о интерфейсах.

Короче говоря, даже если решение, предложенное shmosel, работает; вы, возможно, захотите отступить и подумать, действительно ли это лучший способ решить вашу проблему. Понимаете, звук OO-дизайна и наследования - это больше, чем просто размещение . Здесь можно найти.

+0

Согласен. Забавно, что вы отправили ответ, связанный с моим комментарием, всего через 5 секунд. :-) – Spotted

+0

Добро пожаловать. Извините за прокрасться в голову и украсть эту идею. Но я делаю все возможное, чтобы сутулить мою репутацию. Серьезно: я действительно рад, что я не единственный, кто указывает на (по крайней мере теоретическую) проблему с этим вопросом и принятым ответом. – GhostCat

+0

Без обид (плюс вы выступаете за чистый код). – Spotted

Смежные вопросы