Для событий: потому что нормальная ситуация такова, что у нас есть собственный класс реализации, и может потребоваться прослушать несколько различных событий;мы не можем расширять два разных абстрактных класса.
Скаффман уже объяснил одну проблему с использованием абстрактных классов для RMI.Я бы сделал еще один шаг: абстрактный класс - совершенно неправильное понятие для этой цели.Поставщик услуг должен предоставить своим клиентам информацию о том, как позвонить в службу.Интерфейс - это как раз то, что нам нужно для этого - он сообщает клиенту , что можно сделать, и ничего о , как это делается.Когда мы даем класс Abstract, мы включаем (частичную) информацию о реализации.Клиенту нет необходимости видеть это, и в контексте RMI может даже не быть в состоянии скомпилировать его - абстрактный класс на сервере может ссылаться на классы, которых у клиента даже нет.Конечно, вы можете обрезать все вещи, которые не нужны клиенту, все реализации и т. Д., И вот!Вы вернулись только с информацией, необходимой для интерфейса.
Итак, моя практика:
Определите мои интерфейсы, мой контракт с внешним миром.
Если у меня может быть несколько реализаций этого интерфейса, и особенно если я хочу помочь разработчику, определите абстрактный класс, который реализует интерфейс.Включите общий код реализации в этот абстрактный класс и оставьте некоторые методы абстрактными, чтобы разработчик мог их заполнить.
Или, проще говоря: интерфейс для клиентов, абстрактные классы дляразработчики, и вы вполне можете выбрать использовать оба.И да, это подразумевает некоторое дублирование, и именно поэтому у нас есть хорошие IDE.