I am trying to use template pattern to define a generic algorithm in java.But the method that needs to be overridden, takes an object as input.This object will vary depending on the concrete implementation.So I decided to use inheritance in input parameter. I am passing parent object in the overridden method of the abstract class. In the overriding method of concrete class I downcast it to the child and get the required details. It is said that downcasting is a code smell.How can I achieve this without downcasting.Or is there any other better solution.Example code that shows the issue: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;        ...    }}
Template pattern with varying input type in overridden method
java;design patterns
Use generics to specify the parameter type. The parent class would restrict this parameter to be a subclass of GeneralParameter:abstract class GenericAlgorithm<Param extends GeneralParameter> {    void someMethod(Param p);}Then, the subclass would extend the parent class but provide the used parameter type as a type argument:class ConcreteAlgorithm extends GenericAlgorithm<SpecificParameter> {    @Override    void someMethod(SpecificParameter p) {        ...    }}Note that this may require you to also use generics for other parts of your program if you want to avoid casting. Here's a full (albeit contrived) example that creates 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));See it live on ideone.