这些接口类是否被实例化?

时间:2015-01-14 09:09:23

标签: java

下面的代码来自Lynda.com关于使用Java解析xml的情节。

我被认为接口就像模板一样,你实际上无法实例化它们,但是这个代码在我看来它必须实例化一些标记为接口的类,否则它将如何工作? / p>

请注意,变量doclistitem都来自接口,被使用并对它们进行操作,但它们都来自接口类。我很困惑,希望有人能解释一下:) DocumentElementNodeList都标记为接口。这是代码:

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();
        }
    }

}

3 个答案:

答案 0 :(得分:1)

即使您提到的变量是接口类型,也会为它们分配实现这些接口的类的实例。

例如,builder.parse("http://rss.cnn.com/rss/edition.rss")将返回实现Document接口的类的实例,因此可以将其分配给doc变量。

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

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

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

答案 1 :(得分:1)

如您所见,没有像

这样的命令
 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
    }
}

有关Singleton模式的更多信息,请阅读:http://en.wikipedia.org/wiki/Singleton_pattern

修改
我将在这里为类Bike添加一些示例代码,以显示new Bike()无法工作的原因。

public class Bike implements Vehicle{

    //This is the one and only instance of "Bike" in our whole programm.
    //Whenever you need a Bike, you will have to use this one.
    private static Bike bike = new Bike();

    private Bike(){
        //as you see the constructor is private. Only the Class Bike can instantiate a Bike
        //this is the idea of the Singleton-Pattern. There is one and only one instance of something
        //but this instance can be accessed from (all) other classes.
    }

    public static Bike getInstance(){
        //whoever needs the bike has to call getInstance()
        //We will then pass a reference to the private static bike to whoever needs it, since they cannot 
        //create their own bike via new Bike()
        return bike;
    }

    protected static void drive(){
        System.out.println("Bruuum Bruuuum");
    }

    //Overriding some of the Vehicle-methods here.....

    //whoever holds a reference to our bike can now call this method and of course all the methods
    //provided by our Interface

}

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

Vehicle v = Bike.getInstance();

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

答案 2 :(得分:0)

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

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

您无法创建此类的实例,但在此处您可以获取此类的实例。 我不知道你是否看到了不同之处。