Modello di modello con tipi di input diversi nel metodo sottoposto a override

7

Sto provando a utilizzare il modello di modello per definire un algoritmo generico in java. Ma il metodo che deve essere sovrascritto, prende un oggetto come input. Questo oggetto può variare a seconda dell'implementazione concreta.

Quindi ho deciso di utilizzare l'ereditarietà nel parametro di input. Sto passando l'oggetto genitore nel metodo sottoposto a override della classe astratta. Nel metodo dominante della classe concreta, l'ho scartato al bambino e ottenuto i dettagli richiesti. Si dice che il downcasting sia un odore di codice. Come posso ottenere questo senza downcasting. O c'è qualche altra soluzione migliore.

Esempio di codice che mostra il problema:

abstract class GenericAlgorithm {
    void someMethod(GeneralParameter gp);
}

class ConcreteAlgorithm extends GenericAlgorithm {
    @Override
    void someMethod(GeneralParameter gp) {
        // I can't take a SpecificParameter as argument,
        // so I would need to downcast the parameter
        SpecificParameter sp = (SpecificParameter) gp;
        ...
    }
}
    
posta Rishi 21.12.2014 - 11:46
fonte

1 risposta

7

Usa i generici per specificare il tipo di parametro. La classe genitore limiterebbe questo parametro ad essere una sottoclasse di GeneralParameter :

abstract class GenericAlgorithm<Param extends GeneralParameter> {
    void someMethod(Param p);
}

Quindi, la sottoclasse estenderebbe la classe genitore, ma fornirà il tipo di parametro usato come argomento di tipo:

class ConcreteAlgorithm extends GenericAlgorithm<SpecificParameter> {
    @Override
    void someMethod(SpecificParameter p) {
        ...
    }
}

Nota che questo potrebbe richiedere anche l'uso di generici per altre parti del tuo programma se vuoi evitare il casting. Ecco un esempio completo (anche se forzato) che crea Sandwiches.

abstract class SandwichMaker<S extends Spread> {
    public void make(S spread) {
        toastBread();
        addSpread(spread);
        enjoy();
    }

    protected void toastBread() {
        System.out.println("...toasting bread");
    }

    protected abstract void addSpread(S spread);

    protected void enjoy() {
        System.out.println("this is yummy!");
    }
}

class CheeseSandwichMaker extends SandwichMaker<Cheese> {
    @Override
    protected void addSpread(Cheese cheese) {
        System.out.println("... adding " + cheese.name + " cheese from " + cheese.origin);
    }
}

interface Spread {}
class Cheese implements Spread {
    public final String name;
    public final String origin;

    public Cheese(String name, String origin) {
        this.name = name;
        this.origin = origin;
    }
}

...

SandwichMaker<Cheese> sandwich = new CheeseSandwichMaker();
sandwich.make(new Cheese("Camembert", "Normandy, France"));
sandwich.make(new Cheese("Cheddar", "Somerset, England"));

Guardalo dal vivo su ideone .

    
risposta data 21.12.2014 - 12:22
fonte

Leggi altre domande sui tag