4

I have a class that should have slightly different method implementations based on a parameter I would pass to the class constructor. However, I would like to select which implementation to run at the time of the object creation, and not by always testing a specified parameter. Something of this sort:

public class SomeClass(){
    int parameter=-1;

    SomeClass(int param){
        this.parameter = param;
    }

    public methodSpecific(){ //For when parameter==1;
        Do stuff...
    }

    public methodSpecific(){ //For when parameter==2;
        Do stuff...
    }
}

Instead of:

public class SomeClass(){
    int parameter=-1;

    SomeClass(int param){
        this.parameter = param;
    }

    public methodForAll(){ 
        switch(parameter){
            case 1:
                Do something...

            case 2:
                Do something else...
        }
    }
}

Is there some way I can achieve this?

EDIT: This edit is to clarify the situation and context. Please consider the figure bellow. Rectangles of the same color mean that the implementation of those methods are the same. Rectangles with different colors means even though the name is the same the implementation differs. I need to find a way to implement classA and classB, but without duplicated code, and still allow for class "main" to know that both classA and classB have the same method names and variables.

Ilustrative figure

6
  • Could we have a tiny bit more context ? For now it seems like the switch is fine, but maybe using such a parameter is not what you really want Commented Aug 16, 2015 at 19:06
  • Making 2 methods with same names doing different things is like we would start screaming when we wanted to walk. Commented Aug 16, 2015 at 19:14
  • @mastah Yeah, that or two mammals run in two different ways, even though they are both mammals and both are running. But thanks for the reply anyway. Commented Aug 16, 2015 at 19:53
  • The direction would be a method parameter then :P Commented Aug 16, 2015 at 19:58
  • @Dici Added clarification to the original question. Commented Aug 16, 2015 at 20:18

6 Answers 6

1

I first thought, the straightforward but not wanted implementation would be to have two sub classes of SomeClass, but with the clarification that is actually what you want. Still I edited my example to comply with both the new and old version of the question ;-)

The idea is to hide the different implementations into a set of anonymous classes that implement a the abstract methods of a common base class. The base class is known and called by runMethod1() and runMethod2() and which implementation is used is decided at construction time of SomeClass.

Example:

public class SomeClass()
{
    private abstract class BasicStuff
    {
        // All code that is the same in all implementations go here
        void method1() { /* do something that is always the same */ }

        // All code that shall be different in all implementations go here
        abstract void method2();
    }

    private final BasicStuff whatShallWeDoToday;

    public SomeClass(int param)
    {
        switch (param)
        {   // construct anonymous class with functionallity of ClassA
            case 1: whatShallWeDoToday = new StuffInterface()
                    {
                        void method2() { /* something */ }
                    }
                    break;

            // construct anonymous class with functionallity of ClassB
            case 2: whatShallWeDoToday = new StuffInterface()
                    {
                        void method2() { /* something else */ }
                    }
                    break;

            default:throw IllegalArgumentException();
        }
    }

    public runMethod1()
    { 
        whatShallWeDoToday.method1();
    }

    public runMethod2()
    { 
        whatShallWeDoToday.method2();
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

In some point he has to pick one child class to start with - and probably the selection will be based on somewhere provided parameter, but yes - then the polymorphism will do the trick of picking correct method.
His intention was to do the selection with the constructor parameter (which I would prefer to be an enumerator, by the way), so I provided an example that does the switch/case in the constructor.
1

this can't be achieved by one class. You should probably look at factory design pattern- have an interface for your class, with two implementations, and use the factory to generate the desired class according to your parameter see more details here: http://www.tutorialspoint.com/design_pattern/factory_pattern.htm

2 Comments

all here depends on usage context. Most of approaches are correct here.
I would like to know the semantic of the parameter, because the answer might be that using such a parameter is already bad design. About subclasses, I thought about it two at first, but if there can be hundreds of values for the parameter, well, this does scale very well
0

If you want to fix parameter and do not let it as a parameter provided by method caller, maybe interface is a solution:

public interface SomeClass {
    public void methodSpecific();
}

// for parameter = 1
public class ClassA inplements SomeClass {
    @Override
    public void methodSpecific() {
        ...
    }
}

// for parameter = 2
public class ClassB inplements SomeClass {
    @Override
    public void methodSpecific() {
        ...
    }
}

SomeClass someClass = new ClassA();
someClass.methodSpecific();

Since parameter is fixed when class initialized, you are to decide which class to initialize.

1 Comment

again, inheritance and polymorphism will do the trick, but on some point he has to pick one of child class implementation, and selection will be probably based on somewhere provided parameter.
0

I think that you can't achieve it. With same signature and only for a change in parameter value, you cannot call different methods without switch block.

public class Test{

    int type=1;
    public Test(int type){
        this.type = type;
        switch(type){
            case 1:
                callMethod1();
                break;
            case 2:
                callMethod2();
                break;
            case 3:
                callMethod3();
                break;
        }

    }
    public void callMethod1(){
        System.out.println("in method 1");
    }
    public void callMethod2(){
        System.out.println("in method 2");
    }
    public void callMethod3(){
        System.out.println("in method 3");
    }   
    public static void main(String args[]){
        Test t = new Test(Integer.parseInt(args[0]));
    }
}

Comments

0

It seems that you want two classes instead of one ! SomeClass should be extended by two specialized classes. Depending on the context, it could be an interface or an abstract class if you have some common code to factor out. As you probably want to use a common constructor, an abstract class seems more fitted.

Comments

0

You can't overload methods containing same parameters - every overloaded method has to contain different set of parameters.

Look at your second example. The methodForAll could be just a runMethods(int) and in its switch cases you can run different methods based on provided parameter.

In most of cases to achieve something like this you will need two separate classes implementing an interface or extending a class.

interface Inter{
    public void method();
}

class Type1 implements Inter{
    public void method(){
    System.out.println("Type1 - method()");
    }
}
class Type2 implements Inter{
    public void method(){
        System.out.println("Type2 - method()");
    }
}

public class RunEm {
    Inter type;
    public RunEm(int typeImp){
        switch(typeImp){
        case 1:
            type = new Type1();
            break;
        case 2:
            type = new Type2();
            break;
        }
        type.method(); //this makes an output
    }
    public static void main(String[] args){
        //run case 1
        new RunEm(1);

        //run case 2
        new RunEm(2);
    }

}

Output as expected:

Type1 - method()
Type2 - method()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.