Quando chiamare il costruttore e quando chiamare il metodo in Java?

2

Sto facendo fatica a comprendere appieno l'uso dei costruttori in Java.

Quello che ho imparato finora sui costruttori è il seguente:

  • stesso nome della classe
  • abbreviation ctor
  • sovraccarico
  • nessun tipo di ritorno
  • crea un oggetto di una classe
  • ogni classe ha un costruttore predefinito

Quando per esempio una stringa deve essere restituita da una classe che deve essere chiamata, allora può essere creato un metodo, cioè un costruttore non sarà sufficiente in quanto ciò non restituirà nulla.

Tentativo di rispondere alla domanda

Per spiegare cosa intendo, ho creato una classe con due costruttori e due metodi che restituiscono una stringa.

public class HelloWorldConstructor {
    public HelloWorldConstructor() { }

    public HelloWorldConstructor(String a) {
        saySomething(a);
    }

    public HelloWorldConstructor(String a, String b) {
        saySomething(a, b);
    }

    void saySomething(String a) {
        System.out.println(a);
    }

    void saySomething(String a, String b) {
        System.out.println(a + ", " + b);
    }
}

Opzione 1

È possibile restituire una stringa chiamando il metodo che risiede nella classe.

public class CallConstructor {
    public static void main(String[] args) {
        HelloWorldConstructor hwc = new HelloWorldConstructor();

        hwc.saySomething("allo");
        hwc.saySomething("allo", "allo");
    }
}

restituisce:

allo
allo, allo

Opzione 2

È anche possibile restituire una stringa chiamando direttamente il costruttore.

public class CallConstructor2 {
    public static void main(String[] args) {
        new HelloWorldConstructor("allo");
        new HelloWorldConstructor("allo", "allo");
    }
}

restituisce lo stesso dell'opzione 1.

Discussione

Quando viene scelta l'opzione 2, è necessario creare due oggetti invece di uno come illustrato dall'opzione 1, ma quando scegliere l'opzione 2 e l'opzione 1? In questo caso, penso che sia meglio scegliere l'opzione 1 quando verrà creato un oggetto, ma l'opzione 2 potrebbe essere adatta quando altre circostanze sono applicabili.

Uso di costruttori in Java

The constructor in the example just gives an initial value to class members.

link

Constructors are used to initialize the instances of your classes. You use a constructor to create new objects often with parameters specifying the initial state or other important information about the object

Dopo aver letto di teoria e Q & Per quanto riguarda i costruttori, sto lottando per comprenderli appieno. So come chiamare un costruttore e come chiamare un metodo, ma non riesco a razionalizzare questo.

  • Un costruttore deve essere chiamato direttamente quando ...
  • L'overloading del costruttore verrà eseguito quando ...
  • I metodi verranno chiamati direttamente chiamando il costruttore predefinito quando ...
posta 030 01.01.2018 - 23:50
fonte

4 risposte

6

Si chiama un costruttore quando si desidera creare una nuova istanza di oggetto. Ad esempio se hai una classe Button , allora chiami il costruttore se vuoi creare una nuova istanza Button .

Se non hai bisogno di un nuovo oggetto, non usare un costruttore. Nell'esempio si utilizza semplicemente il costruttore come un modo complesso di chiamare un metodo, ma in realtà non si utilizza l'oggetto creato (il risultato di new -expression) per qualcosa. Questo è un chiaro suggerimento che non è necessario chiamare un costruttore. Se hai fatto saySomething static non avresti bisogno di chiamare alcun costruttore.

Il motivo della tua confusione è probabilmente che la classe HelloWorldConstructor non ha alcuno scopo oltre la scrittura dell'output. Pertanto non è ovvio se dovresti avere una o due istanze di esso. In realtà non hai bisogno di alcuna istanza.

    
risposta data 02.01.2018 - 09:01
fonte
4

same name as class

Vero, in java

abbreviation ctor

True

overloading

True

no return type

Bene ... nessun ritorno esplicito. Un operatore ha sempre un tipo di ritorno implicito. La classe è il tipo. Un operatore, se utilizzato con la nuova parola chiave, restituisce l'oggetto che crea e il tipo di oggetto è la classe. Per fortuna, quando definisci un ctor non devi più pronunciare il nome della classe.

create an object of a class

Questo è quello che fa.

every class has a default constructor

Bene ... no. Come dice wikipedia:

In both Java and C#, a "default constructor" refers to a nullary constructor that is automatically generated by the compiler if no constructors have been defined for the class. The default constructor implicitly calls the superclass's nullary constructor, then executes an empty body.

Wikipedia: Default Constructor

Quindi no, non tutte le classi hanno un costruttore predefinito. Ogni classe avrà qualche costruttore. Ha solo il costruttore predefinito se non ne definisci uno esplicitamente.

BTW, "costruttore di nullità" è un modo elegante per dire un costruttore senza argomenti.

When for example a string has to be returned from a class that needs to be called then a method could be created, i.e. a constructor will not be sufficient as this will not return anything.

Ugg. Guarda, ci sono costruttori che "restituiscono" le stringhe va bene. Vivono tutti nella classe String .

In order to explain what I mean, I have created a class with two constructors and two methods that return a string.

No, non l'hai fatto. L'uscita non sta tornando. I tuoi costruttori non restituiscono stringhe. Loro "restituiscono" oggetti del tipo HelloWorldConstructor .

Questo è il motivo per cui viene compilato:

HelloWorldConstructor hwc = new HelloWorldConstructor();

Option 1: it is possible to return a string by calling the method that resides in the class.

Sarebbe se i metodi restituissero le stringhe. Restituiscono nulla. Di nuovo, l'output non viene restituito.

Option 2: It is also possible to return a string by calling the constructor directly.

Intendi dire produrre una stringa. Sì, puoi fare in modo che un costruttore faccia altre cose oltre a costruire semplicemente l'oggetto, come voleva Dio. Ciò non significa che sia una buona idea .

When option 2 is chosen, then two objects have to be created instead of one as depicted by option 1, but when to choose option 2 and when option 1? In this case I think it is better to choose option 1 as one object will be created, but option 2 could be suitable when other circumstances are applicable.

La costruzione di oggetti e l'uso di oggetti dovrebbero avvenire in luoghi separati. Schiacciarle insieme in questo modo fa solo un casino.

A constructor has to be called directly when ...

Quando costruisci l'oggetto. Mettilo in una variabile maneggevole e passalo a qualcosa che possa usarlo.

Constructor overloading will be done when ...

... non puoi decidere da cosa dipende il tuo oggetto. Se riesci a pensare a molti modi per costruire lo stesso oggetto, allora scrivi molti costruttori che lo costruiscono in tanti modi.

Methods will be called directly by calling the default constructor when ...

Spiacente, questo non ha senso Chiami metodi sugli oggetti quando è il momento di usarli. Chiami costruttori (predefiniti o meno) quando è il momento di costruirli.

Ancora una volta, non devi costruirlo e usarlo allo stesso tempo. In realtà di solito è meglio se non lo fai. Il polimorfismo funziona solo quando non sai esattamente a cosa stai parlando.

When to call the constructor and when to call the method in Java?

La migliore risposta che ho ricevuto proviene da Iniezione delle dipendenze che dice di eseguire la costruzione più in alto possibile nello stack delle chiamate. Il che significa in sostanza la costruzione principale. Personalmente non mi dispiace se usi alcuni Pattern creativi che ti portano fuori dal main per un po 'ma mantengono il codice di comportamento lontano da lì.

    
risposta data 02.01.2018 - 09:12
fonte
3

Il nostro compito come programmatori è quello di offrire l'automazione a vari domini del mondo reale - fare questo spesso ci impone di rappresentare vari concetti di dominio, le loro relazioni, i loro comportamenti o capacità.

Nella programmazione, rappresentiamo vari concetti, relazioni e comportamenti usando le capacità del linguaggio di programmazione per definire le astrazioni. Astrazioni, perché mentre da un lato modellano alcuni concetti, relazioni e comportamenti del dominio, dall'altro lato hanno dettagli di implementazione interna (ad esempio stato e algoritmi) che preferiamo proteggere dal programmatore client consumante (spesso noi stessi ) per ridurre la complessità e facilitare gli oneri del programmatore.

La classe è un meccanismo per la creazione di astrazione. Consente il raggruppamento di metodi e stato in una singola entità che può essere manipolata da un programmatore client che consuma.

È importante sottolineare che il costrutto di classe consente istanze personalizzabili. La personalizzazione dell'istanza viene in genere eseguita tramite i parametri passati ai costruttori. I costruttori offrono la possibilità di associare un'istanza a determinati valori o determinati altri oggetti.

Una volta costruito, ora è possibile utilizzare un'istanza per accedere ai comportamenti e alle relazioni del concetto, utilizzando i suoi metodi.

Tipico dell'utilizzo di astrazioni, separiamo le preoccupazioni e creiamo oggetti in un posto e li usiamo in altri: la creazione di oggetti rappresenta una pietra miliare di alcuni tipi, e una volta creata, un'istanza può essere distribuita per essere utilizzata da altri utenti programmatore client, in grado di lavorare con diverse istanze di oggetti dello stesso tipo (classe o interfaccia) indipendentemente dal modo in cui sono state create.

La tua classe HelloWorldConstructor , ovviamente è solo un campione arbitrario per gli scopi della tua domanda - normalmente non nomineremo una classe dopo la capacità di costruire, ma dopo l'astrazione rappresentata dalle sue istanze.

Questa classe è anche troppo semplicistica in quanto non ha nessuno stato. (Anche se a volte è ragionevole avere un'istanza senza stato, scenari utili di solito coinvolgono più classi diverse che condividono qualche interfaccia (o classe base)). Senza stato, il costruttore non vincola nulla - per dirla in altro modo, il costruttore non sta partecipando alla creazione di un'istanza personalizzata.

Tuttavia, tutto ciò che viene detto, l'opzione 1 è più nello stile della programmazione orientata agli oggetti che nell'altra perché crea un'istanza e successivamente la usa, anche se lo fa in linee di codice immediatamente adiacenti.

La tua opzione 2 è effettivamente una forma procedurale di programmazione (cioè non OOP) poiché stai facendo tutto il lavoro nel costruttore e poi buttando via l'istanza che è stata creata.

Uno scenario tipico consiste nell'usare il costruttore per personalizzare un'istanza e quindi, una volta creato, passare l'istanza personalizzata a un altro codice generico che può funzionare con qualsiasi istanza di tale classe. Questo codice più generico esegue quindi alcuni comportamenti utili con l'istanza personalizzata.

Ad esempio, aggiungi un parametro al costruttore per prendere un nome come stringa. Ora il compito del costruttore è semplicemente quello di catturare quel nome.

public class SayHi {
    private String name;

    public SayHi(String toWhom) {
        name = toWhom;  // capture customization parameter
    }

    public void saySomething(String a) {
        System.out.println(name + ": " + a);
    }
}

Ora possiamo creare istanze personalizzate in modo diverso new SayHi("Erik") ... new SayHi("030") e utilizzare quelle istanze differenti con lo stesso codice.

    
risposta data 02.01.2018 - 01:23
fonte
-5
  • A constructor has to be called directly when ...

Mai.

Invochi un costruttore utilizzando la parola chiave new e la JVM invocherà il costruttore per te.

  • Constructor overloading will be done when ...

Scrivi codice fragile.

Il sovraccarico del costruttore significa che hai più di un costruttore nella stessa classe .

I costruttori dovrebbero impostare ( final ) variabili di istanza (ovvero membri o campi ) dell'oggetto (e nient'altro tranne le semplici convalide). Poiché i diversi costruttori devono avere tipi di parametri diversi o conteggio di parametri diversi, la conseguenza di averli è uno dei quattro casi:

  1. Imposta solo i membri che hanno parametri correlati passati nel singolo ctor.

    Il risultato di questo è che devi assegnare null ai membri non relativi a un parametro del corrente ctor. Questo di solito significa che hai un oggetto non valido che ti obbliga a lanciare assegni null nel tuo codice.

  2. Assegnate alcuni valori predefiniti ai membri non relativi a un parametro del corrente ctor o chiamate un altro ctor in questa classe che passa i parametri correnti e quei valori predefiniti. (concatenamento del costruttore)

    La conseguenza di ciò è che nascondi le reali dipendenze della tua classe dall'utente. Gli utenti della tua classe potrebbero essere confusi.

  3. "Calcoli" i valori mancanti.

    I medici non dovrebbero fare alcun calcolo, solo inizializzando i membri. Qualsiasi altra cosa renderà la tua classe difficile da riutilizzare.

  4. Acquisisci valori mancanti accedendo a metodi statici in altre classi (singeltons per caso ...)

    Questo è il caso peggiore poiché crea un accoppiamento indistruttibile indistruttibile con questa classe (singeton).

Come regola generale: una classe dovrebbe avere solo un ctor.

  • Methods will be called directly by calling the default constructor when ...

Mai.

Un costruttore (come già scritto) assegna solo valori ai membri. Non calcola nulla e quindi non dovrebbe chiamare nessun altro metodo all'interno della classe.

Man mano che diventi esperto potresti trovare validi motivi per frenare queste regole, ma come principiante dovresti attenervisi.

    
risposta data 02.01.2018 - 01:06
fonte

Leggi altre domande sui tag