В Guava ImmutableCollection
есть подклассы, такие как ImmutableList
, которые являются (не расширяемыми) абстрактными классами, а не интерфейсами.Документация говорит, что это предотвращает внешний подтип.С другой стороны, в документации также говорится, что они
должны рассматриваться как интерфейсы во всех важных смыслах
Но разве способность к внешнему подтипу не важна?интерфейса?Например, если бы ImmutableList
был интерфейсом, я мог бы иметь сигнатуру метода, такую как
public ImmutableList<String> getNames();
(в соответствии с рекомендациями Гуавы), и затем иметь гибкость для замены в пользовательской реализации ImmutableList
в будущем.Однако, поскольку в действительности это абстрактный класс, у меня нет такой гибкости, и поэтому я связан с реализациями Guava.Таким образом, если я хочу сохранить эту гибкость, мне придется вернуться к более общему типу возврата List
, который больше не передает вызывающей стороне полезную информацию об неизменности:
public List<String> getNames();
почему важно, чтобы они не были внешне подтипированы?Одним из ответов может быть то, что дизайнеры Guava не доверяют внешним разработчикам должную поддержку требуемой семантики, но сам по себе List
имеет довольно обширный контракт, и никто не мешает его реализовать на заказ.Или есть другие причины?