2010-05-16 14 views
10

Quali sono i casi d'uso di avere due costruttori con la stessa firma?Perché dovresti avere due costruttori con la stessa firma?

Modifica: non è possibile farlo in Java a causa del quale Java efficace dice che è necessario un factory statico. Ma mi stavo chiedendo perché dovresti farlo in primo luogo.

+1

erm, non puoi, puoi? –

+5

Per prima cosa, ti dispiacerebbe mostrarci un esempio che compila? –

+0

Per la cronaca, intendi due costruttori * nella stessa classe * con la stessa firma? – harpo

risposta

15

Il motivo faresti pensa si voleva fare questo è che ti sei trovato in una situazione in cui tipo di variabile non è contesto sufficiente.

Per esempio, potrei ingannare me stesso nel pensare che ho bisogno di dare ai miei due costruttori della classe Point: uno che funzioni con X e Y, e uno per gradi e radianti. Entrambi potrebbero essere rappresentati come float.

Quindi penso che mi servivano due costruttori con firme identiche (float, float).

Dr.Bloch sottolinea che è meglio per rendere metodi di fabbrica:


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

Per inciso, un'altra alternativa ai metodi di fabbrica è quello di creare tipi che portano il contesto che manca dai tipi di dati, come questo:


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

Se pensi che questo sia più chiaro dei metodi di fabbrica è una questione di gusti. In questo caso specifico, il mio sentimento è che le due classi di coordinate sono utili solo se il tuo progetto rende le coordinate utili per conto proprio, separate da un punto a quelle coordinate.

5

Una classe non può avere due costruttori con la stessa firma.

From the JLS:

8.8.2 Constructor Firma

Si tratta di un errore di compilazione di dichiarare due costruttori con esclusione-equivalente (§8.4.2) le firme in una classe. È un errore in fase di compilazione per dichiarare due costruttori la cui firma ha la stessa cancellazione (§4.6) in una classe.

+2

Sono consapevole che Java non lo consente. Questo è il motivo per cui abbiamo bisogno di una fabbrica statica. Ma perché dovremmo creare diversi costruttori nel posto. – unj2

2

Non lo faresti, e non puoi comunque. Non compilerebbe i file di classe in bytecode poiché non è possibile per il programma distinguere tra loro per decidere quale utilizzare.

+0

In realtà, la risoluzione del sovraccarico avviene in fase di compilazione, quindi il programma non esisterà mai cercando di trovare il costruttore giusto. – Joey

+4

Non è quello che ho detto, o ti ho appena frainteso? – AaronM

1

@kunjaan - ci sono pochissimi casi d'uso per un'idea del genere anche se esistesse un modo tecnicamente valido per farlo (che in Java non c'è - vedi altre risposte).

Un possibile caso d'uso sarebbe una diversa implementazione del costruttore basata su alcune condizioni esterne - ad esempio, un costruttore che potrebbe allocare una certa memoria se non fosse disponibile, o riutilizzare quella memoria da qualche pool comune nel programma se divenne disponibile.

Un altro esempio potrebbe essere un costruttore che implementa determinate cose utilizzando una chiamata di sistema più efficiente se l'architettura corrente supporta quella chiamata di sistema. A proposito, entrambi questi esempi sono un po 'più difficili da immaginare in Java, ma sono più facili da immaginare in C++ -land, ma si spera che l'idea generale venga raggiunta.

In entrambi i casi, questo sarebbe in realtà codificato o avendo una fabbrica come già detto, OPPURE con un singolo costruttore, che implementa una sorta di decisione basata sull'ambiente e chiama un metodo di supporto con diverse firme per eseguire effettivamente l'inizializzazione necessaria questo dipende dall'implementazione, ad es (In pseudocodice, linguaggio indipendente)

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

Per rispondere alla tua nuova domanda modificata, l'intento sarebbe se tu avessi una classe che potrebbe avere due azioni logicamente diverse ma che capita di essere la stessa firma.

Ad esempio, supponete di avere una classe Persona che si preoccupa del nome e del luogo di nascita di qualcuno.

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

Ovviamente, questo non funziona.

Devi usare una fabbrica:

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

Ovviamente un esempio forzato, ma questa è l'idea generale ...

+0

Questo è un ottimo esempio. – unj2

11

Il motivo si vorrebbe avere due (o più) i costruttori con il stessa firma è che il tipo di dati non è sinonimo di significato.

Un semplice esempio potrebbe essere una classe Line.

Ecco un costruttore: public class Line(double x1, double y1, double x2, double y2)

Ecco un altro: public class Line(double x1, double y1, double angle, double distance)

Il primo costruttore definisce due estremità di una linea. Il secondo costruttore definisce un punto finale e l'angolo e la distanza dal secondo punto finale.

Java non è in grado di distinguere tra i due costruttori di classe Line, vero. Ma ci sono buone ragioni per 2 o più costruttori per avere la stessa firma.

+1

+1: la prima frase è il punto chiave. –

Problemi correlati