为什么java.io.OutputStream
不建模为接口而不是抽象类?
我想,一个接口可以证明对单元测试很有用。
实际上,java.io.OutputStream(与 java.io.InputStream 相同)使用了装饰器模式。与问题相关,以下是来自(Head First Design Patterns page 93)的回复:
关键是装饰器必须与它们要装饰的对象具有相同的类型。所以这里我们使用继承来实现类型匹配,但我们没有使用继承来获取行为。
所以这就是为什么在这种情况下我们更喜欢继承(AbstracClass)而不是接口(多态)。但请注意,在大多数其他情况下,原则是相反的:“优先组合(接口)而不是继承(抽象类) ”。
一些方法已经实现。这对于接口是不可能的。
close()
void flush()
void write(byte[] b)
void write(byte[] b, int off, int len)
已经使用默认实现实现。
javadoc给出了一个提示:
需要定义 OutputStream 子类的应用程序必须始终提供至少一个写入一个字节输出的方法。
(即void write(int b) throws IOException
)
如果你看它的实际代码,write()
这个基础抽象类的默认其他方法使用你需要实现的唯一方法。
此外,输出流可能未链接到实际资源(ByteArrayOutputStream
例如):因此,此类也具有默认实现,.close()
并且.flush()
什么都不做,并且只需要被具有实际资源的流覆盖。
至于测试目的,单元测试的唯一区别实际上是您需要extends
而不是implements
,并且不要忘记覆盖您需要的方法。或使用模拟库(例如 mockito、jmock 或...)。
它可能是一个抽象类,因为除了它的一个方法之外,所有方法都是具体的(实现的)......并且您可以在需要其他东西(用于测试)时对其进行子类化,或者在某些测试情况下也可以模拟它...... .
它被制作为抽象类,因此可以将其视为接口。
关于OutputStream
不同interface
的类提供方法的默认实现write
。