10

为什么java.io.OutputStream不建模为接口而不是抽象类?

我想,一个接口可以证明对单元测试很有用。

4

5 回答 5

2

实际上,java.io.OutputStream(与 java.io.InputStream 相同)使用了装饰器模式。与问题相关,以下是来自(Head First Design Patterns page 93)的回复:

关键是装饰器必须与它们要装饰的对象具有相同的类型。所以这里我们使用继承来实现类型匹配,但我们没有使用继承来获取行为。

所以这就是为什么在这种情况下我们更喜欢继承(AbstracClass)而不是接口(多态)。但请注意,在大多数其他情况下,原则是相反的:“优先组合(接口)而不是继承(抽象类) ”。

在此处输入图像描述

于 2013-01-11T11:51:32.937 回答
2

一些方法已经实现。这对于接口是不可能的。

close() 
void flush() 
void write(byte[] b) 
void write(byte[] b, int off, int len) 

已经使用默认实现实现。

于 2013-01-10T16:41:24.003 回答
2

javadoc给出了一个提示:

需要定义 OutputStream 子类的应用程序必须始终提供至少一个写入一个字节输出的方法。

(即void write(int b) throws IOException

如果你看它的实际代码,write()这个基础抽象类的默认其他方法使用你需要实现的唯一方法。

此外,输出流可能未链接到实际资源(ByteArrayOutputStream例如):因此,此类也具有默认实现,.close()并且.flush()什么都不做,并且只需要被具有实际资源的流覆盖。

至于测试目的,单元测试的唯一区别实际上是您需要extends而不是implements,并且不要忘记覆盖您需要的方法。或使用模拟库(例如 mockito、jmock 或...)。

于 2013-01-10T16:41:38.193 回答
1

它可能是一个抽象类,因为除了它的一个方法之外,所有方法都是具体的(实现的)......并且您可以在需要其他东西(用于测试)时对其进行子类化,或者在某些测试情况下也可以模拟它...... .

于 2013-01-10T16:42:25.807 回答
0

它被制作为抽象类,因此可以将其视为接口。

关于OutputStream不同interface的类提供方法的默认实现write

于 2013-01-10T16:38:53.230 回答