Pregunta ¿Por qué una clase abstracta "DocumentBuilderFactory" permitió crear instancias nuevas?


Recientemente, he estado trabajando con analizadores XML. Esto apenas comienza para mí y pude entender cómo usar clases de analizador DOM en Java, es decir DocumentBuilderFactory y DocumentBuilder para analizar un documento XML.

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

Lo que me pregunto es por qué surgen clases abstractas, como DocumentBuilderFactory y DocumentBuilder, se les permite instanciar nuevas instancias? Y luego en otro ejemplo veo:

Calendar calendar = Calendar.getInstance();  
System.out.println(calendar.get(Calendar.DATE)); 
  1. Por lo que sé, no puede crear instancias (en otras palabras, crear un objeto) para clases abstractas y de interfaz. ¿Estoy en lo correcto?
  2. Hacer getInstance() y newInstancce() ¿Los métodos crean instancias de las clases abstractas anteriores?

¿Me estoy perdiendo algo sobre el uso de una clase abstracta y sus nuevos Objetos?


5
2018-05-11 07:04


origen


Respuestas:


Ese método es un método de fábrica abstracto, que devuelve un subclase de DocumentBuilder, que es una implementación (concreta).

No es importante saber la clase exacta del objeto, solo necesita saber que es una DocumentBuilder. El método puede devolver una instancia decidida en el tiempo de ejecución, o predeterminada según lo considere conveniente.

Si tiene curiosidad por saber, puede imprimir la clase real de esta manera:

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

Tenga en cuenta que el método newInstance() No debe confundirse con el método del mismo nombre de Class, es decir, estos dos son diferentes:

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

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

Una desafortunada elección de nombre que seguramente causó confusión.


9
2018-05-11 07:07



Eso es un método estático abstracto de fábrica , que devolverá un subtipo de DocumentBuilderFactory no es la instancia real de DocumentBuilderFactory En sí. No es como lo que presumo, entiendes:

DocumentBuilderFactory dbf = new DocumentBuilderFactory();

DocumentBuilderFactory # newInstance () , Obtenga una nueva instancia de un DocumentBuilderFactory. Este método estático crea una nueva instancia de fábrica. Este método usa la siguiente búsqueda ordenada procedimiento para determinar la clase de implementación de DocumentBuilderFactory para cargar.


3
2018-05-11 07:08



Es un método estático. Puede llamar a métodos estáticos de clases abstractas (o de cualquier clase) sin una referencia a una instancia.


1
2018-05-11 07:09



Gracias por todos, después de intentar codificar debajo de mi duda se aclaró.

Calendar cls = Calendar.getInstance ();
  Fecha dt = nueva Fecha ();
  System.out.println (cls.getClass ()); // <------ 1
          DocumentBuilderFactory dbls = DocumentBuilderFactory.newInstance ();           System.out.println (dbls.getClass ()); // <------ 2
          DocumentBuilder db = dbls.newDocumentBuilder ();
          System.out.println (db.getClass ()); // <-------- 3

Y veo la siguiente salida:

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

a) el método estático "DocumentBuilderFactory.newInstance ()" devuelve una instancia de clase de subtipo llamada "DocumentBuilderFactoryImpl".

b) "DocumentBuilderFactoryImpl" es una subclase de la clase abstracta "DocumentBuilderFacotory", por lo tanto, no hay problema si doy:

DocumentBuilderFacotryImpl dbls = DocumentBuilderFactory.newInstance ();
  // ----- En lugar de dar DocumentBuilderFactory dbls = DocumentBuilderFactory.newInstance ();

y lo mismo se aplica a DocumentBuilderImpl db = dbls.newDocumentBuilder ();
  // ---- En lugar de DocumentBuilder db = dbls.bewDocumentBuilder ();

Conclusión: newInstance (), newDocumentBuilder (), getInstance () devuelve el objeto de subclase. Aunque la clase abstracta no puede crear un nuevo objeto, podemos asignar un objeto de subclase a la variable de referencia de la clase abstracta (es decir, a los padres). ex:

Clase abstracta A   }
   la clase B extiende A {   }

podemos decir:

 A a = new B();   

pero no

 A a = new A();

1
2018-05-12 12:05