Как вызвать метод Java на основе типа подкласса?

Я пытаюсь отправить объекты отдельному методу согласно их подклассу.

Например, рассмотрите те 2 объекта

class A extends I {}
class B extends I {}

и метод

void dispatch(I i) {}

в dispatch(), Я хотел бы вызвать метод согласно типу i. Следовательно, если i на самом деле имеет тип, handlerA(A a) метод назовут. Если это имеет тип B, handlerB(B b) будет назван, и так далее... Я попробовал перегрузкой метода, но я предполагаю, что она не прокладывает себе путь

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

Заранее спасибо,

править: Я не могу изменить ни один из тех классов.

8
задан pinpinlelapin 30 January 2010 в 22:56
поделиться

6 ответов

С момента вашего редактирования я предполагаю, что не можете редактировать A, B и I; Это приводит к плохим новостям:

Вы можете наследовать из A , скажем C в этом классе (C) вы можете позвонить Super.Dispatch () , чтобы вы Может достичь базового класса A.Dispatch () .

  • Но из-за дизайна (безсовершенствованного наследства) вы не можете достичь I . Это было бы похоже на звонок Super.super, который не допускается

  • в Java, вы не можете позвонить Super (). Super () .. Участье акселирует их родителям, но не на свои бабушки и дедушки.

Так что вы жертва плохого дизайна. Редактировать: Исправлена ​​опечатка

1
ответ дан 5 December 2019 в 20:16
поделиться

Если бы вы могли использовать Scala, вы можете написать

i match {
  case a: A => handlerA(a) 
  case b: B => handlerB(b)
  case _ => throw new Exception("Unknown i: " + i.toString)
}
0
ответ дан 5 December 2019 в 20:16
поделиться

Похоже, что единственный способ сделать это, это использовать тип проверки. Я понимаю, что это не должно поощряться, но ...

void dispatch(I i)
{
   if(i instanceof A)
   {
      handlerA();
   } 
   else 
   {
      handlerB();
   }
}

, но серьезно, если вы можете избежать его вообще, не пишите код так. Если вы не можете их изменить, не могли бы вы по-прежнему расширить A и B, добавить другой обработчик () для обоих и и использовать эти новые подклассы вместо A и B?

0
ответ дан 5 December 2019 в 20:16
поделиться

Используйте Visitor Pattern .

Короче говоря, пусть I объявит метод accept(Visitor ...) и пусть Visitor выставит onA(A ...), onB(B ...) и т.д. методы. Ваша реализация интерфейса I вызовет соответствующий метод на переданном в Visitor.

Вероятно, это не стоит того (из-за boilerplate), если у Вас только 2 конкретных класса, но где-то около 3 или 4, это начинает стоить того - если только для того, чтобы избежать дублирования конструкций if-else.

4
ответ дан 5 December 2019 в 20:16
поделиться

Итак, в I вы объявляете метод handler() и реализуете его соответствующим образом (т.е. по-разному) и в A, и в B.

Это полиморфизм :)

.
3
ответ дан 5 December 2019 в 20:16
поделиться

Я думаю, что шаблон адаптера более применим, чем шаблон посетителя в этом случае.

0
ответ дан 5 December 2019 в 20:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: