Sé que no es posible definir un constructor en una interfaz. Pero me pregunto por qué, porque creo que podría ser muy útil.
Por lo tanto, puede estar seguro de que algunos campos de una clase están definidos para cada implementación de esta interfaz.
Por ejemplo, considere la siguiente clase de mensaje:
public class MyMessage {
public MyMessage(String receiver) {
this.receiver = receiver;
}
private String receiver;
public void send() {
//some implementation for sending the mssage to the receiver
}
}
Si se define una interfaz para esta clase de modo que pueda tener más clases que implementen la interfaz de mensajes, solo puedo definir el método de envío y no el constructor. Entonces, ¿cómo puedo asegurarme de que cada implementación de esta clase realmente tenga un conjunto de receptores? Si uso un método como setReceiver(String receiver)
no puedo estar seguro de que realmente se llama a este método. En el constructor podría asegurarlo.
Respuestas:
Tomando algunas de las cosas que ha descrito:
... estos requisitos son exactamente para lo que son las clases abstractas .
fuente
Message
interfaz que defina elsend()
método, y si Sebi desea proporcionar una clase "base" para implementaciones de laMessage
interfaz, proporcione también unaAbstractMessage
. Las clases abstractas no deberían tomar el lugar de las interfaces, nunca intentaron sugerirlo.Un problema que se presenta cuando se permiten constructores en las interfaces proviene de la posibilidad de implementar varias interfaces al mismo tiempo. Cuando una clase implementa varias interfaces que definen diferentes constructores, la clase tendría que implementar varios constructores, cada uno de los cuales satisface una sola interfaz, pero no las otras. Será imposible construir un objeto que llame a cada uno de estos constructores.
O en código:
fuente
class A implements Named, HashList { A(){HashList(new list()); Named("name");} }
new Set<Fnord>()
pudiera interpretar que significa "Dame algo que pueda usar como unSet<Fnord>
"; Si el autorSet<T>
pretendíaHashSet<T>
ser la implementación de referencia para cosas que no tenían una necesidad particular de otra cosa, la interfaz podría definirsenew Set<Fnord>()
como sinónimo denew HashSet<Fnord>()
. Para que una clase implemente múltiples interfaces no representaría ningún problema, yanew InterfaceName()
que simplemente construiría una clase designada por la interfaz .A(String,List)
constructor podría ser el constructor designado,A(String)
yA(List)
podría ser uno secundario que lo llame. Su código no es un contraejemplo, solo uno pobre.Una interfaz define un contrato para una API, que es un conjunto de métodos que acuerdan tanto el implementador como el usuario de la API. Una interfaz no tiene una implementación instanciada, por lo tanto, no tiene un constructor.
El caso de uso que describe es similar a una clase abstracta en la que el constructor llama a un método de un método abstracto que se implementa en una clase secundaria.
El problema inherente aquí es que mientras se ejecuta el constructor base, el objeto hijo aún no se construye y, por lo tanto, en un estado impredecible.
Para resumir: es pedir problemas cuando llama a métodos sobrecargados de constructores principales, para citar mindprod :
fuente
Una solución que puede intentar es definir un
getInstance()
método en su interfaz para que el implementador sepa qué parámetros deben manejarse. No es tan sólido como una clase abstracta, pero permite más flexibilidad como una interfaz.Sin embargo, esta solución requiere que use el
getInstance()
para instanciar todos los objetos de esta interfaz.P.ej
fuente
Solo hay campos estáticos en la interfaz que no necesitan inicializarse durante la creación de objetos en la subclase y el método de la interfaz debe proporcionar una implementación real en la subclase. Por lo tanto, no hay necesidad de un constructor en la interfaz.
Segunda razón: durante la creación del objeto de la subclase, se llama al constructor principal.
fuente
Si desea asegurarse de que cada implementación de la interfaz contenga un campo específico, simplemente necesita agregar a su interfaz el captador para ese campo :
Receiver
objeto debe pasar a la clase de alguna manera (ya sea por constructor o por instalador)fuente
Las dependencias a las que no se hace referencia en los métodos de una interfaz deben considerarse como detalles de implementación, no como algo que la interfaz impone. Por supuesto, puede haber excepciones, pero como regla general, debe definir su interfaz como cuál se espera que sea el comportamiento. El estado interno de una implementación dada no debería ser una preocupación de diseño de la interfaz.
fuente
Vea esta pregunta para saber por qué (tomado de los comentarios).
Si realmente necesita hacer algo como esto, es posible que desee una clase base abstracta en lugar de una interfaz.
fuente
Esto se debe a que las interfaces no permiten definir el cuerpo del método en él, pero deberíamos tener que definir el constructor en la misma clase que las interfaces tienen por defecto un modificador abstracto para todos los métodos a definir. Es por eso que no podemos definir constructor en las interfaces.
fuente
Aquí hay un ejemplo usando esta técnica. En este ejemplo específico, el código está haciendo una llamada a Firebase usando un simulacro
MyCompletionListener
que es una interfaz enmascarada como una clase abstracta, una interfaz con un constructorfuente
private
modificador de accesointerface
?Generalmente los constructores son para inicializar miembros no estáticos de una clase particular con respecto al objeto.
No hay creación de objetos para la interfaz, ya que solo hay métodos declarados pero no métodos definidos. ¿Por qué no podemos crear objetos para métodos declarados? La creación de objetos es nada más que asignar algo de memoria (en memoria de almacenamiento dinámico) para miembros no estáticos.
JVM creará memoria para los miembros que están completamente desarrollados y listos para usar. Basado en esos miembros, JVM calcula la cantidad de memoria requerida para ellos y crea memoria.
En el caso de los métodos declarados, JVM no puede calcular la cantidad de memoria necesaria para estos métodos declarados, ya que la implementación será en el futuro, lo que no se ha hecho en este momento. entonces la creación de objetos no es posible para la interfaz.
conclusión:
sin la creación de objetos, no hay posibilidad de inicializar miembros no estáticos a través de un constructor. Es por eso que el constructor no está permitido dentro de una interfaz (ya que no hay uso del constructor dentro de una interfaz)
fuente