Разве ObjectInputStream не должен расширять FilterInputStream?

Блоки цитирования из Документов Java -

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

DataInputStream позволяет приложению считать примитивные типы данных Java из базового входного потока машинно-независимым способом.

DataInputStream поэтому расширяется FilterInputStream

ObjectInputStream десериализовывает примитивные данные и возражает ранее записанному использованию ObjectOutputStream.

Однако по некоторым причинам ObjectInputStream НЕ расширяется FilterInputStream даже при том, что это также читает объекты (на этот раз и не типы примитивов) от базового входного потока. Вот ветвление соответствующих классов.

alt text

Есть ли существует дизайн, рассуждающий для того же?

5
задан Vaibhav Bajpai 24 May 2010 в 12:37
поделиться

3 ответа

Разумный вопрос. Подумав об этом, я считаю, что Object * Stream мог быть разработан для расширения Filter * Stream (то же самое относится к Output или Input). Почему этого не сделали? Возможно, потому что:

  1. Это не дает реальной пользы. Как объяснил Мацей, суть Filter * Stream , помимо некоторой неважной организации классов, состоит в том, чтобы обеспечить некоторую общую (и довольно тривиальную) реализацию по умолчанию тех классов, которые имеют этот шаблон (чтение / запись из некоторого базового потока, в конечном итоге преобразование потока), которые будут расширены другими классами (из Java API или пользователя). Но Filter * Stream не касается интерфейсов : вы почти никогда не найдете или не реализуете какой-либо метод, который требует, например, аргумента Filter * Stream . Следовательно, решение о наследовании класса * Stream или Filter * Stream , когда есть альтернатива, в основном является решением реализации; пользователям класса в основном все равно.

  2. Разработчики ObjectOutputStream решили дать дополнительную гибкость тем, кто желает расширить класс, полностью переопределив его, предоставив дополнительный пустой конструктор (без базового OuputStream ). Эта функция (я думаю, довольно редкая) ставит класс (с точки зрения концепции и реализации) немного дальше от класса Filter * Stream . Опять же, это не кажется убедительным.

3
ответ дан 14 December 2019 в 13:28
поделиться

Существует различие между:

  • Логическим наследованием (разделяет интерфейс)
  • Наследованием «кода» при совместном использовании кода между классами

Логически LinkedList является не AbstractList , поскольку он не является абстрактным. Однако с точки зрения кода полезно совместно использовать некоторые реализации методов List , поскольку они могут быть реализованы с точки зрения других, обычно с такой же эффективностью (например, isEmpty может быть реализовано как size () == 0 ).

Некоторые платформы, такие как GObject (или, в некоторой степени, Haskell - хотя это не объектно-ориентированный язык, и многие вещи совершенно разные) допускают реализацию методов по умолчанию в интерфейсе, который его определяет.

Однако это не относится к Java, которая использует классы Abstract * для повторного использования кода. Filter * Stream не столько определяет, что вывод куда-то отправляется (поскольку весь смысл ввода-вывода Java заключается в том, что производителю / получателю все равно), но он используется для повторного использования общего кода.

2
ответ дан 14 December 2019 в 13:28
поделиться

Думаю, ObjectInputStream пришлось переопределить каждый метод FilterInputStream.

Когда вы делаете это, на самом деле нет смысла поддерживать эти отношения.

Что важно: ObjectInputStream IS InputStream (вы по-прежнему можете записывать в него примитивные данные в дополнение к другим методам), и эта связь существует.

1
ответ дан 14 December 2019 в 13:28
поделиться
Другие вопросы по тегам:

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