Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java OutputStream作为接口_Java_Interface_Io - Fatal编程技术网

Java OutputStream作为接口

Java OutputStream作为接口,java,interface,io,Java,Interface,Io,为什么java.io.OutputStream没有建模为接口而不是抽象类 我认为,接口可以被证明是有用的,例如单元测试。它是作为抽象类创建的,因此可以将其视为接口 关于OutputStream与接口不同,该类为方法write提供默认实现,其中一些方法已经实现。这对于接口是不可能的 close() void flush() void write(byte[] b) void write(byte[] b, int off, int len) 已使用默认实现实现。javadoc给出了一个提

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


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

它是作为抽象类创建的,因此可以将其视为接口


关于
OutputStream
接口不同,该类为方法
write

提供默认实现,其中一些方法已经实现。这对于接口是不可能的

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

已使用默认实现实现。

javadoc给出了一个提示:

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

(也就是说,
voidwrite(intb)抛出IOException

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

此外,输出流可能不会链接到实际资源(例如,
ByteArrayOutputStream
):因此,此类还具有
.close()
.flush()
的默认实现,这些实现不做任何事情,只需要由后面有实际资源的流覆盖


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

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

事实上,java.io.OutputStream(与java.io.InputStream相同)使用。关于这个问题,以下是(第93页)的回复:

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

这就是为什么我们更喜欢继承(类)而不是接口 (多面体)在这种情况下。但请注意,在大多数其他情况下, 原则是相反的:“偏爱成分(界面)而不是 继承(抽象类)



好吧,您可以使用模拟库进行单元测试Mockito确实提供了一种测试抽象类的方法,即spy。但是spy(s)要求您提供一个具体的实现,这个实现不被认为是干净的。。。无论如何,对于你的问题来说,这有点离题;)我想纠正我自己。jmock似乎提供了一些扩展(ClassImposteriser)来正确模拟抽象类。拥有抽象类而不是接口有什么好处?#抽象类的好处:有些方法已经可以实现了。缺点:您不能扩展多个类,但可以实现多个接口。@GangnamStyleOverflower错误:在Java 8(尚未最终版本)之前,您不能在接口中实现方法,因此优点是您可以实现(其中的一些)方法。@GangnamStyleOverflower错误:我是这么说的:@MrSmith42您可以始终拥有一个实现接口的抽象类。他们可以轻松地创建接口和抽象类class@Steve郭:通常两者兼得会很好,但可悲的是,孙经常决定不这样做-(是的,看起来是这样。他们忽略了当时可能不相关的设计选择?也可以使用接口实现类型匹配?请参阅Decorator pattern的Wikipedia页面中的Java示例以获取一些插图。是的,但我们需要的是一个框架实现。在某些情况下,接口不允许有方法实现在某些情况下,我们需要一个抽象的框架实现类。这也是Java集合框架背后的想法(正如Joshua Bloch在他的著作《有效Java,第18项:首选接口而非抽象类》中所解释的那样)。争论的焦点是为什么不在AbstractInputStreamBase(框架实现)的基础上再加上一个InputStream接口。(集合是界面驱动设计的一个很好的例子。)虽然,Java可以通过InputStream交互和AbstractInputStreamBase实现同样的效果。Jmock确实提供了足够的扩展来模拟与模拟接口一致的抽象类。感谢指针。是的,当然,但它真的值得吗?接口都很好,但滥用它们会导致代码更复杂比其他情况下更复杂。可能是口味的问题!到目前为止,我可以得出的结论是,当前的InputStream现在是我们必须处理的遗留类。它从1996年发布的Jdk 1.0开始就存在了。不确定当时的主流单元测试实践如何。