【问题标题】:How come an abstract class "DocumentBuilderFactory" allowed to instantiate new instance为什么允许实例化新实例的抽象类“DocumentBuilderFactory”
【发布时间】:2013-05-05 20:55:42
【问题描述】:

最近,我一直在使用 XML 解析器。这对我来说才刚刚开始,我设法理解了如何在 java 中使用 DOM 解析器类,即 DocumentBuilderFactoryDocumentBuilder 来解析 XML 文档。

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();  
DocumentBuilder db = dbf.newDocumentBuilder();            

我问自己的是,为什么抽象类,例如 DocumentBuilderFactoryDocumentBuilder,可以实例化新实例?然后在另一个例子中我看到:

Calendar calendar = Calendar.getInstance();  
System.out.println(calendar.get(Calendar.DATE)); 
  1. 据我所知,您不能实例化(换句话说,创建对象)抽象类和接口类。我说的对吗?
  2. getInstance()newInstancce() 方法是否创建上述抽象类的实例?

我是否遗漏了有关使用抽象类及其新对象的某些内容?

【问题讨论】:

    标签: java oop abstract-class instantiation


    【解决方案1】:

    感谢大家,在尝试了以下代码后,我的疑问得到了解决。

    日历 cls = Calendar.getInstance();
    日期 dt = new Date();
    System.out.println(cls.getClass()); // DocumentBuilderFactory dbls = DocumentBuilderFactory.newInstance(); System.out.println(dbls.getClass()); // DocumentBuilder db = dbls.newDocumentBuilder();
    System.out.println(db.getClass()); //

    我看到以下输出:

     ********Output******
       class java.util.GregorianCalendar
       class com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
       class com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl
    

    a) 静态方法“DocumentBuilderFactory.newInstance()”返回名为“DocumentBuilderFactoryImpl”的子类型类实例。

    b)“DocumentBuilderFactoryImpl”是抽象“DocumentBuilderFacotory”类的子类,因此如果我给出没有问题:

    DocumentBuilderFacotryImpl dbls = DocumentBuilderFactory.newInstance();
    //-----而不是给 DocumentBuilderFactory dbls = DocumentBuilderFactory.newInstance();

    同样适用于 DocumentBuilderImpl db = dbls.newDocumentBuilder();
    //---- 而不是 DocumentBuilder db = dbls.bewDocumentBuilder();

    结论:newInstance()、newDocumentBuilder()、getInstance()返回子类对象。虽然抽象类不能创建新的 Object ,但我们可以将子类对象分配给抽象类(即父)引用变量。例如:

    抽象类 A{ }
    B 类扩展 A{ }

    我们可以说:

     A a = new B();   
    

    但不是

     A a = new A();
    

    【讨论】:

    • 是的,我想你已经明白了。
    【解决方案2】:

    那个方法是一个abstract factory method,它返回一个DocumentBuilder子类,这是一个(具体的)实现。

    知道对象的确切类并不重要,您只需要知道它是DocumentBuilder。该方法可以返回一个在运行时决定的实例,或者它认为合适的预定实例。

    如果你想知道,你可以像这样打印出实际的类:

     System.out.println(dbf.getClass());
    

    注意newInstance()的方法不要与Class的同名方法混淆,即两者是不同的:

     // a static method of this class
     DocumentBuilderFactory.newInstance(); 
    
    // an instance method of Class
     DocumentBuilderFactory.class.newInstance();
    

    一个不幸的名字选择肯定会引起混乱。

    【讨论】:

    • 我对我的问题添加了一些额外的内容。
    • @Bohemian just curios.. DocumentBuilderFactory 类当然可以被视为一个 AbstractFactory,因为它公开了诸如 newDocumentBuilder 之类的方法以返回其他对象实例。然而 DocumentBuilderFactory.newInstance() 或多或少是一个静态工厂方法
    • @DevBlanked No DocumentBuilderFactory.newInstance() 是一个 abstract 工厂方法,因为返回的类型 DocumentBuilderFactory 是一个 abstract` 类。根据定义,如果返回的类型是接口或抽象类,则工厂方法是 *abstract,这基本上意味着返回的实例必须是声明的返回类型的子类。跨度>
    • @Bohemain ...你可以检查我的答案,它在底部。对不起,如果你根本不明白。我希望,我的脑子里有正确的概念。
    【解决方案3】:

    这是一个静态抽象工厂方法,它会返回DocumentBuilderFactory的子类型,而不是DocumentBuilderFactory本身的实际实例。它不像我想象的那样,你懂的:

    DocumentBuilderFactory dbf = new DocumentBuilderFactory();
    

    DocumentBuilderFactory#newInstance()获取 DocumentBuilderFactory 的新实例。这个静态方法创建一个新的工厂实例。此方法使用以下有序查找过程来确定要加载的 DocumentBuilderFactory 实现类。

    newInstance() 将返回DocumentBuilderFactory 的实现类(子类型)的实例,它不是抽象的,并将对该对象的引用分配给 DocumentBuilderFactory 引用变量。

    【讨论】:

    • 正是我假设: DocumentBuilderFactory dbf = new DocumentBuilderFactory(); .当您说“它将返回子类型”时,我想知道子类型类。对不起,我快到了,但我的想法很微妙。
    • 我明白了,我已经调查了源代码。感谢您的帮助。
    • ....你能检查我的答案吗,在底部。对不起,如果你根本不明白。我希望,我的脑子里有正确的概念。
    【解决方案4】:

    这是一个静态方法。您可以在不引用实例的情况下调用抽象类(或任何类)的静态方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-01
      • 2019-06-09
      • 2014-07-12
      • 2022-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多