5

块引号来自 Java Docs -

FilterInputStream 包含一些其他输入流,它用作其基本数据源,可能沿途转换数据或提供附加功能。

DataInputStream 允许应用程序以与机器无关的方式从底层输入流中读取原始 Java 数据类型。

因此DataInputStream延伸FilterInputStream

ObjectInputStream 反序列化以前使用 ObjectOutputStream 编写的原始数据和对象。

但是,由于某种原因,即使它也在从底层输入流中读取对象(这次不是原始类型),它也ObjectInputStream不会扩展。FilterInputStream这是相关类的分支。

替代文字

是否有相同的设计理由?

4

3 回答 3

3

明智的问题。考虑到这一点,我相信它Object*Stream可以被设计为扩展Filter*Stream(同样适用于输出或输入)。为什么没有这样做?也许是因为:

  1. 它没有带来真正的好处。正如 Maciej 所解释的Filter*Stream,除了一些不重要的类组织之外,它的重点是为那些具有该模式的类提供一些常见的默认(而且相当简单)实现(从一些底层流读/写,最终转换流) , 由其他类(来自 Java API 或用户)扩展。但Filter*Stream接口无关:例如,您几乎永远不会找到或实现某些需要Filter*Streamas 参数的方法。因此,当有替代方案时,使类继承*Stream或的决定主要是实现决定;Filter*Stream类的用户基本不会在意。

  2. 的设计者ObjectOutputStream决定为那些愿意扩展类的人提供额外的灵活性,通过提供一个额外的空构造函数 (没有底层OuputStream)来完全重新实现它。这个特性(我认为相当罕见)使类(在概念和实现方面)与类相距甚远Filter*Stream。同样,这似乎还没有定论。

于 2010-05-24T13:17:31.987 回答
2

有以下区别:

  • 逻辑继承(共享接口)
  • 在类之间共享代码时的“代码”继承

逻辑LinkedList上不是AbstractList,因为它不是抽象的。然而,从代码的角度来看,共享一些List方法的实现是有益的,因为它们可以根据其他方法实现,通常具有相同的效率(例如isEmpty可以实现为size() == 0)。

某些平台,例如 GObject(或在某种程度上扩展 Haskell - 尽管它不是 OO 语言并且许多事情完全不同)允许在定义它的接口中默认实现方法。

然而,Java 并非如此,它使用Abstract*类来重用代码。Filter*Stream与其说是定义输出发送到某处(因为 Java I/O 的全部意义在于生产者/接收者不在乎),但它用于重用公共代码。

于 2010-05-24T12:53:45.770 回答
1

我猜 ObjectInputStream 必须重写 FilterInputStream 的每个方法。

当你这样做时,维持这种关系并没有真正的意义。

重要的是:ObjectInputStream一个 InputStream(除了其他方法之外,您仍然可以向其写入原始数据)并且存在这种关系。

于 2010-05-24T12:43:31.880 回答