在我目前遇到的一个问题中(用Java将文件打印到物理打印机),我一直在像疯子一样运行代码,试图吞噬所用每个类的javadoc中任何有用的遗漏信息。
现在,我从之前的问题中提取了相当多的代码,所以有相当一部分代码不是我自己写的。我注意到的问题是,我获取的代码正在初始化一个对象,比如实现接口(Doc)的"SimpleDoc",并将其分配给该接口?!
小代码片段:
Doc mydoc = new SimpleDoc(textStream, flavor, null);
现在,据我所知,在java中,我们创建对象。我熟悉继承,也熟悉使用接口允许一个类"继承"多个超类的技巧。
但这并不正确。你可以创建一个实现接口的类,这对我来说很好。但当一个接口被创建,一个对象被简化为它的接口时,会发生什么?当我准确引用mydoc时,我访问的是什么?
您不能创建接口,您在这里所做的是创建实现接口Doc
的类SimpleDoc
的对象mydoc
。因为类实现了这个接口,所以可以将mydoc
当作该接口的实例来处理。这允许您访问接口中所有声明的方法,这些方法在类SimpleDoc
中实现
例如,如果您的文档界面如下所示:
public interface Doc {
void print();
}
您的SimpleDoc类将如下所示:
public class SimpleDoc implements Doc {
public void clear() { ... }
@Override
public void print() { ... }
}
则只能访问mydoc
-对象的print()
-方法。但你也可以说:
SimpleDoc mydoc = new SimpleDoc();
然后您也可以调用clear()
诀窍是要意识到您不是在"创建"、"实例化"或"初始化"接口。您只是将一个变量定义为您知道实现该接口的东西。
您实际上是在告诉其他编写此代码的程序员,对于此方法的其余部分,您只对myDoc
是Doc
(即满足Doc
接口的东西)这一事实感兴趣。这可以使编程变得更简单,因为IDE的自动完成现在只向您显示由该接口定义的方法,而不是SimpleDoc
能够执行的所有操作。
想象一下,在未来,您希望扩展您的功能,以便根据某些输入实现不同的Doc。不是显式地创建SimpleDoc,而是说:
Doc mydoc = docFactory.getByType(inputType);
docFactory
可以生成任何类型的Doc
,这个方法并不真正关心实例化的是哪种类型,因为不管怎样,它都会像对待Doc
一样对待它。