Quali sono gli svantaggi di non dichiarare un metodo di classe statico?

1

Sulla traccia "Interfacce" sul sito Web di Oracle, viene presentato il seguente scenario:

Imagine a futuristic society where computer-controlled robotic cars transport passengers through city streets without a human operator. Automobile manufacturers write software (Java, of course) that operates the automobile—stop, start, accelerate, turn left, and so forth. Another industrial group, electronic guidance instrument manufacturers, make computer systems that receive GPS (Global Positioning System) position data and wireless transmission of traffic conditions and use that information to drive the car.

The auto manufacturers must publish an industry-standard interface that spells out in detail what methods can be invoked to make the car move (any car, from any manufacturer). The guidance manufacturers can then write software that invokes the methods described in the interface to command the car. Neither industrial group needs to know how the other group's software is implemented. In fact, each group considers its software highly proprietary and reserves the right to modify it at any time, as long as it continues to adhere to the published interface. (http://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html)

Quindi creiamo un'interfaccia come questa:

public interface OperateCar {

   // constant declarations, if any

   // method signatures

   // An enum with values RIGHT, LEFT
   int turn(Direction direction,
            double radius,
            double startSpeed,
            double endSpeed);
   int changeLanes(Direction direction,
                   double startSpeed,
                   double endSpeed);
   int signalTurn(Direction direction,
                  boolean signalOn);
   int getRadarFront(double distanceToCar,
                     double speedOfCar);
   int getRadarRear(double distanceToCar,
                    double speedOfCar);
         ......
   // more method signatures
}

e implementalo come:

public class OperateBMW760i implements OperateCar {

    // the OperateCar method signatures, with implementation --
    // for example:
    int signalTurn(Direction direction, boolean signalOn) {
       // code to turn BMW's LEFT turn indicator lights on
       // code to turn BMW's LEFT turn indicator lights off
       // code to turn BMW's RIGHT turn indicator lights on
       // code to turn BMW's RIGHT turn indicator lights off
    }

    // other members, as needed -- for example, helper classes not 
    // visible to clients of the interface
}

Fin qui tutto bene. Ora supponiamo che, inoltre, ogni costruttore di automobili sia tenuto a creare un prototipo di auto e supponiamo che, per qualche motivo, desideriamo tenere traccia di queste vetture prototipo. Una soluzione è aggiungere un nuovo metodo all'interfaccia OperateCar :

public OperateCar getPrototype();

Quindi ogni classe di implementazione potrebbe implementare questo metodo restituendo la sua auto prototipo. Ma c'è un problema con questo: l'auto prototipo non ha nulla a che fare con l'istanziazione della classe di implementazione; invece, appartiene alla classe stessa. In altre parole, se non avessimo l'interfaccia, dichiareremmo automaticamente questo metodo come static . Ma non possiamo farlo qui, perché le interfacce Java non consentono metodi statici.

Quali sono i problemi associati a non dichiarare un metodo di classe statico? Va bene in questo caso solo per lasciare la parola chiave static in modo che compaia il codice? O gli svantaggi sono così grandi che è meglio cercare un'altra soluzione?

    
posta John Gowers 17.03.2014 - 15:23
fonte

3 risposte

7

public OperateCar getPrototype(); è essenzialmente un metodo di fabbrica. La tua domanda si riduce sostanzialmente a questo: se ho un metodo di fabbrica, ma non sono autorizzato a inserirlo nella mia interfaccia, allora come posso renderlo statico?

Ovviamente la risposta è che non puoi. Ma non hai comunque bisogno di quella capacità.

Mi aspetto che un metodo statico di fabbrica faccia parte di ... una fabbrica. Mi aspetto che il metodo factory restituisca un'istanza della tua interfaccia.

In altre parole, non è necessario il metodo statico nell'interfaccia. Una volta creato l'oggetto, un metodo statico nell'interfaccia diventerebbe comunque inutile, a meno che non si intenda generare nuovi oggetti dall'oggetto esistente.

    
risposta data 17.03.2014 - 16:27
fonte
2

the prototype car has nothing to do with any instantiation of the implementing class; instead, it belongs to the class itself. In other words, if we didn't have the interface, we'd automatically declare this method as static.

È possibile che una classe "auto" possa ereditare lo stesso stesso prototipo di un altro?
Potrebbe il 760i condividere un prototipo comune con, per esempio, il 760? Se è così, l'implementazione di getPrototype () verrebbe dalla superclasse e quindi non potrebbe essere statica.
E comunque, se il tuo obiettivo è quello di "tenere traccia" dei prototipi, sicuramente potrebbe esserci un numero di loro per un dato modello di produzione degno di nota?

La tua interfaccia non (e non dovrebbe) preoccuparsi di come il metodo è implementato in una particolare classe - solo fino a quando è implementato.

    
risposta data 17.03.2014 - 16:22
fonte
0

Se ho capito bene, un produttore di automobili è l'unica fonte di automobili (incluso il prototipo). È solo l'interfaccia che deve essere pubblica. E quell'interfaccia dovrebbe fornire un modo per accedere al prototipo (per qualsiasi motivo), ma nessuno al di fuori del processo di produzione costruirà il prototipo. Usando queste ipotesi ...

L'interfaccia dovrebbe infatti avere un metodo getPrototype () di alcuni tipi. È solo questione di come il prototipo è stato inserito nell'attuale implementazione dell'auto. Questo prototipo (reale) inserito può essere facilmente statico.

class MyCarManufactory() {
    OperateCar buildNewCar(OperateCar prototype) {
        // build your car here
    }
}

Mentre la tua auto può avere il seguente aspetto:

public class OperateBMW760i implements OperateCar {
    private static OperateCar prototype;

    OperateCar getPrototype() {
        return prototype;
    }

    int signalTurn(Direction direction, boolean signalOn) {
       // code to turn BMW's LEFT turn indicator lights on
       // code to turn BMW's LEFT turn indicator lights off
       // code to turn BMW's RIGHT turn indicator lights on
       // code to turn BMW's RIGHT turn indicator lights off
    }

    // other members, as needed -- for example, helper classes not 
    // visible to clients of the interface
}

Non c'è nulla di male usando un metodo di istanza per accedere a un campo statico. In effetti, le informazioni sul tuo prototipo in realtà sono statiche non sono di preoccupazione di nessuno.

    
risposta data 17.03.2014 - 17:44
fonte

Leggi altre domande sui tag