Блоки цитирования из Документов Java -
FilterInputStream содержит некоторый другой входной поток, который он использует в качестве своего основного источника данных, возможно преобразовывая данные по пути или обеспечивая дополнительную функциональность.
DataInputStream позволяет приложению считать примитивные типы данных Java из базового входного потока машинно-независимым способом.
DataInputStream
поэтому расширяется FilterInputStream
ObjectInputStream десериализовывает примитивные данные и возражает ранее записанному использованию ObjectOutputStream.
Однако по некоторым причинам ObjectInputStream
НЕ расширяется FilterInputStream
даже при том, что это также читает объекты (на этот раз и не типы примитивов) от базового входного потока. Вот ветвление соответствующих классов.
Есть ли существует дизайн, рассуждающий для того же?
Разумный вопрос. Подумав об этом, я считаю, что Object * Stream
мог быть разработан для расширения Filter * Stream
(то же самое относится к Output или Input). Почему этого не сделали? Возможно, потому что:
Это не дает реальной пользы. Как объяснил Мацей, суть Filter * Stream
, помимо некоторой неважной организации классов, состоит в том, чтобы обеспечить некоторую общую (и довольно тривиальную) реализацию по умолчанию тех классов, которые имеют этот шаблон (чтение / запись из некоторого базового потока, в конечном итоге преобразование потока), которые будут расширены другими классами (из Java API или пользователя). Но Filter * Stream
не касается интерфейсов : вы почти никогда не найдете или не реализуете какой-либо метод, который требует, например, аргумента Filter * Stream
. Следовательно, решение о наследовании класса * Stream
или Filter * Stream
, когда есть альтернатива, в основном является решением реализации; пользователям класса в основном все равно.
Разработчики ObjectOutputStream
решили дать дополнительную гибкость тем, кто желает расширить класс, полностью переопределив его, предоставив дополнительный пустой конструктор (без базового OuputStream
). Эта функция (я думаю, довольно редкая) ставит класс (с точки зрения концепции и реализации) немного дальше от класса Filter * Stream
. Опять же, это не кажется убедительным.
Существует различие между:
Логически LinkedList
является не AbstractList
, поскольку он не является абстрактным. Однако с точки зрения кода полезно совместно использовать некоторые реализации методов List
, поскольку они могут быть реализованы с точки зрения других, обычно с такой же эффективностью (например, isEmpty
может быть реализовано как size () == 0
).
Некоторые платформы, такие как GObject (или, в некоторой степени, Haskell - хотя это не объектно-ориентированный язык, и многие вещи совершенно разные) допускают реализацию методов по умолчанию в интерфейсе, который его определяет.
Однако это не относится к Java, которая использует классы Abstract *
для повторного использования кода. Filter * Stream
не столько определяет, что вывод куда-то отправляется (поскольку весь смысл ввода-вывода Java заключается в том, что производителю / получателю все равно), но он используется для повторного использования общего кода.
Думаю, ObjectInputStream пришлось переопределить каждый метод FilterInputStream.
Когда вы делаете это, на самом деле нет смысла поддерживать эти отношения.
Что важно: ObjectInputStream IS InputStream (вы по-прежнему можете записывать в него примитивные данные в дополнение к другим методам), и эта связь существует.