2010-05-16 9 views
10

¿Cuáles son los casos de uso de tener dos constructores con la misma firma?¿Por qué tendría dos constructores con la misma firma?

Editar: No se puede hacer eso en Java debido a que Effective Java dice que necesita fábrica estática. Pero me preguntaba por qué tendrías que hacer eso en primer lugar.

+1

erm, usted no puede, ¿verdad? –

+5

Primero, ¿te importaría mostrarnos un ejemplo que compila? –

+0

Para el registro, ¿te refieres a dos constructores * en la misma clase * con la misma firma? – harpo

Respuesta

15

La razón és piensan que quería hacer esto es que usted se ha encontrado en una situación en la que el tipo de variable no es suficiente contexto.

Por ejemplo, podría engañarme a mí mismo al pensar que tengo que darle mis constructores de la clase Point dos: uno que funciona por X e Y, y uno por grados y radianes. Ambos pueden ser representados como float.

Así que creo que necesitaba dos constructores con firmas idénticas (flotar, flotar).

Dr.Bloch señala que es mejor hacer métodos de fábrica:


    public static Point newPointByDegreesAndRadians (float degrees, float radians); 
    public static Point newPointByXandY (float x, float y); 

Por cierto, otra alternativa a los métodos de fábrica es la creación de tipos que llevan el contexto en el que no se encuentra en los tipos de datos, como esto:


    public class CoordinatesXY { 
     float X; 
     float Y; 
     ... 
    } 
    public class CoordinatesDegreesRadians { 
     float degrees; 
     float radians; 
     ... 
    } 
    public Point (CoordinatesXY coordinates) { ... } 
    public Point (CoordinatesDegreesRadians coordinates) { ... } 

Si usted piensa que esto es más claro que los métodos de fábrica es una cuestión de gusto. Para este caso específico, tengo la sensación de que las dos clases de coordenadas solo son útiles si el diseño hace que las coordenadas sean útiles por sí mismas, separadas de un punto en esas coordenadas.

5

Una clase no puede tener dos constructores con la misma firma.

From the JLS:

8.8.2 Constructor Firma

es un error de tiempo de compilación para declarar dos constructores con (§8.4.2) las firmas de anulación en el equivalente en una clase. Es un error en tiempo de compilación declarar dos constructores cuya firma tiene el mismo borrado (§4.6) en una clase.

+2

Soy consciente de que Java no permite eso. Es por eso que necesitamos fábrica estática. Pero ¿por qué necesitaríamos crear diferentes constructores en el lugar? – unj2

2

No lo haría, y no puede de todos modos. No compilará los archivos de clase en bytecode ya que no hay forma de que el programa diferencie entre ellos para decidir cuál usar.

+0

En realidad, la resolución de sobrecarga ocurre en tiempo de compilación, por lo que el programa no existirá tratando de encontrar el constructor correcto. – Joey

+4

¿No es eso lo que dije o simplemente te he entendido mal? – AaronM

1

@kunjaan - hay muy pocos casos de uso para tal idea, incluso si hubiera una forma técnicamente válida para hacerlo (que en Java no existe - ver otras respuestas).

Un posible caso de uso sería diferentes implementaciones de constructor basadas en alguna condición externa; por ejemplo, un constructor que podría asignar cierta memoria si no estuviera disponible, o reutilizar esa memoria desde algún grupo común en el programa si estuvo disponible

Otro ejemplo de eso sería un constructor que implementaría ciertas cosas utilizando una llamada al sistema más eficiente si la arquitectura actual soportara esa llamada al sistema. Por cierto, estos dos ejemplos son un poco más difíciles de imaginar en Java, pero es más fácil de imaginar en C++, pero se obtiene la idea general con suerte.

En cualquier caso, esto sería codificado ya sea por tener una fábrica como usted mencionó O tener un único constructor, que implementa algún tipo de decisión basada en el entorno y llama a un método auxiliar con diferentes firmas para realizar la inicialización necesaria eso depende de la implementación, por ejemplo (En pseudocódigo, independiente del lenguaje)

function helper_initializer(signature for case 1) { 

} 
function helper_initializer(signature for case 2) { 

} 
function constructor() { 
    // constructor logic here 
    if (environmental_consdition() == 1) { 
     this->helper_initializer(signature for case 1); 
    } else { 
     this->helper_initializer(signature for case 2); 
    } 
} 
3

Para responder a su nueva pregunta editada, la intención sería si tuviera una clase que podría tener dos acciones lógicamente diferentes pero que resultan ser de la misma firma.

Por ejemplo, supongamos que tiene una clase de persona que se preocupa por el nombre y el lugar de nacimiento de alguien.

public Person(String name) { ... } 
public Person(String placeOfBirth) { ... } 

Obviamente, esto no funciona.

Usted tiene que usar una fábrica:

public static Person personWithName(String name) { ... } 
public static Person personFromPlace(String placeOfBirth) { ... } 

Obviamente, un ejemplo artificial, pero esa es la idea general ...

+0

Este es un gran ejemplo. – unj2

11

La razón por la que le gustaría tener dos (o más) de constructores con la la misma firma es que el tipo de datos no es sinónimo de significado.

Un ejemplo simple sería una clase de línea.

Aquí hay uno constructor: public class Line(double x1, double y1, double x2, double y2)

Aquí hay otro: public class Line(double x1, double y1, double angle, double distance)

La primera constructor define dos puntos extremos de una línea. El segundo constructor define un punto final, y el ángulo y la distancia al segundo punto final.

Java no puede distinguir entre los dos constructores de la clase Line, verdadero. Pero hay buenas razones para que 2 o más constructores tengan la misma firma.

+1

+1 - la primera oración es el punto clave. –

Cuestiones relacionadas