下面的代码来自Lynda.com关于使用Java解析xml的情节。
我被认为接口就像模板一样,你实际上无法实例化它们,但是这个代码在我看来它必须实例化一些标记为接口的类,否则它将如何工作? / p>
请注意,变量doc
,list
和item
都来自接口,被使用并对它们进行操作,但它们都来自接口类。我很困惑,希望有人能解释一下:) Document
,Element
和NodeList
都标记为接口。这是代码:
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();
}
}
}
答案 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。
您无法创建此类的实例,但在此处您可以获取此类的实例。 我不知道你是否看到了不同之处。