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

问题描述 投票:0回答:5

为什么

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

接口可以证明是有用的,例如,我认为 jUnit 测试。

java junit interface io outputstream
5个回答
2
投票

部分方法已经实施。这对于接口来说是不可能的。

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

已经使用默认实现来实现。


2
投票

javadoc给出了提示:

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

(即

void write(int b) throws IOException

如果你看一下它的实际代码,这个抽象基类的默认其他

write()
方法使用你需要实现的唯一方法。

此外,输出流可能不会链接到实际资源(例如

ByteArrayOutputStream
):因此,此类还具有
.close()
.flush()
的默认实现,它们不执行任何操作,并且仅需要由具有以下功能的流覆盖:他们背后的实际资源。

就测试目的而言,单元测试的唯一区别实际上是您需要

extends
而不是
implements
,并且不要忘记重写您需要的方法。或者使用模拟库(例如mockito,或jmock,或...)。


2
投票

事实上,java.io.OutputStream(与java.io.InputStream相同)使用了Decorator模式。与该问题相关,以下是来自(Head First Design Patterns第93页)的回复:

重点是装饰器具有相同的类型是至关重要的 作为他们要装饰的物体。所以这里我们使用 继承来实现类型匹配,但我们没有使用 继承以获得行为。

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

enter image description here


1
投票

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


0
投票

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

关于

OutputStream
interface
不同,该类为方法
write
提供了默认实现。

© www.soinside.com 2019 - 2024. All rights reserved.