Java 这些接口类是否正在实例化?

Java 这些接口类是否正在实例化?,java,Java,下面的代码来自Lynda.com关于用Java解析xml的一集 我一直认为接口就像模板一样,您无法实际实例化它们,但在我看来,这段代码必须实例化一些标记为接口的类,否则它将如何工作 请注意,变量doc、list和item都来自接口,它们被使用并对其进行操作,但它们都来自接口类。我很困惑,希望有人能解释:)文档,元素和节点列表都标记为接口。代码如下: import java.io.IOException; import javax.xml.parsers.DocumentBuilder; imp

下面的代码来自Lynda.com关于用Java解析xml的一集

我一直认为接口就像模板一样,您无法实际实例化它们,但在我看来,这段代码必须实例化一些标记为接口的类,否则它将如何工作

请注意,变量
doc
list
item
都来自接口,它们被使用并对其进行操作,但它们都来自接口类。我很困惑,希望有人能解释:)
文档
元素
节点列表
都标记为接口。代码如下:

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;



public class ReadXML {

    public static void main(String[] args) {
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse("http://rss.cnn.com/rss/edition.rss");

            NodeList list = doc.getElementsByTagName("title");
            System.out.println("There are " + list.getLength() + " items.");

            for (int i = 0; i < list.getLength(); i++) {
                Element item = (Element)list.item(i);
                System.out.println(item.getFirstChild().getNodeValue());
            }

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
import java.io.IOException;
导入javax.xml.parsers.DocumentBuilder;
导入javax.xml.parsers.DocumentBuilderFactory;
导入javax.xml.parsers.parserConfiguration异常;
导入org.w3c.dom.Document;
导入org.w3c.dom.Element;
导入org.w3c.dom.NodeList;
导入org.xml.sax.SAXException;
公共类ReadXML{
公共静态void main(字符串[]args){
试一试{
DocumentBuilderFactory工厂=DocumentBuilderFactory.newInstance();
DocumentBuilder=factory.newDocumentBuilder();
Document doc=builder.parse(“http://rss.cnn.com/rss/edition.rss");
节点列表=doc.getElementsByTagName(“标题”);
System.out.println(“有”+list.getLength()+“项”);
对于(int i=0;i
即使您提到的变量属于接口类型,它们也是实现这些接口的类的指定实例

例如,
builder.parse(“http://rss.cnn.com/rss/edition.rss“”
将返回实现
文档
接口的类的实例,因此可以将其分配给
文档
变量

这与创建类的实例并将其分配给接口变量没有什么不同。例如:

List<String> list = new ArrayList<String>();
List List=new ArrayList();

仅使用接口类型时,不需要知道实现接口的类。

DocumentBuilderFactory是一个抽象类(用抽象关键字声明,其中某些类是抽象的。这不能实例化。但是DocumentBuilderFactory提供了方法newInstance,并提供了DocumentBuilderFactory的实例请参见

DocumentBuilder使用DocumentBuilderFactory方法newDocumentBuilder()提供DocumentBuilder

您无法创建此类的实例,但在这里可以获得此类的实例。
我不知道您是否看到了差异。

正如您所看到的,没有类似的命令

 Document doc = new Document()
 //...
因为这将尝试创建一个接口的实例,正如您所知,这是无法完成的。
这段代码的作用是在实现这些被引用接口的对象上创建一些引用。

class Demo{

    public static void main(String[] args){

         //assuming we have the classes Car and Bus which implement the Interface
         // Vehicle
         Car mycar = new Car(); //Creates new Instance of Car on the Heap
         Bus mybus = new Bus(); //Creates new Instance of Bus on the Heap


         // Now let's try to access them with our interface.
         // By doing so you lose access to all methods and 
         // attributes of your car/bus which are not described in your
         // Interface! 
         Vehicle myvehicle = new Vehicle(); //This will not work!
         Vehicle myvehicle = mycar; //This is fine

         // Lets assume there is another class called "Bike" which 
         // cannot be instantiated directly (keyword: Singleton) but  
         // implements Vehicle             
         Bike mybike = new Bike(); //This won't work!
         Vehicle mybike = Bike.getInstance(); //This is fine
    }
}
有关单例模式的更多信息,请阅读以下内容:

编辑:
我将在这里为类Bike添加一些示例代码,以说明
newbike()
无法工作的原因。

如您所见,
newbike()
只能从类本身调用,因为它是一个私有方法。
我们可以根据需要创建对“Bike”唯一实例的任意多个引用,但是所有引用都将始终引用同一个对象
由于自行车实现了车辆,我们还可以创建自行车车辆部分的参考,该参考将自行车投射到车辆上

Vehicle v = Bike.getInstance();

但是没有办法获得另一个Bike或Vehicle实例。

对不起,我不明白。它们似乎被指定为接口类类型的项,就像我阅读它的方式一样。例如NodeList list=doc.getElementsByTagName(“title”);//创建一个名为list的节点列表类型变量。因此,我们现在有了一个实例化的节点列表类型。@如果您编写
System.out.println(list.getClass().getName()),则有十次
您将看到列表变量包含实现NodeList的某个实际类的对象。您不能实例化接口。只能实例化实现该接口的类。@十次在您的计算机上运行此示例,您将看到哪些类正在实现此实例interfaces@user902383我有前男友我想知道的是,它在什么范围内“决定”或“知道”什么特定类(从接口继承而来)要实际使用?是在方法的返回类型中吗?我一直支持你,直到自行车。到目前为止,我得到的是可以有一个类型接口的引用,它指向一个类型的对象,该类型的对象实际上可以实例化。因此,即使你不能创建对象,你也可以有一个“bucket”(或变量)它引用了一个实现的更具体的对象。我到了吗?我在getInstance上迷路了-这似乎完全违反直觉?嘿,十次了,是的,你是对的。在我的示例中,自行车仅限于自行车的一个实例,用户/程序员无法创建新自行车。唯一现有的自行车居住在自行车内我会给我的例子添加一些源代码和解释,也许这会让事情变得更清楚。
Vehicle v = Bike.getInstance();