根据构造函数中的参数使用不同的方法

时间:2015-08-16 18:57:03

标签: java constructor polymorphism

我有一个类应该根据我传递给类构造函数的参数略有不同的方法实现。但是,我想选择在创建对象时运行哪个实现,而不是始终测试指定的参数。这种东西:

$evalAsync

而不是:

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...
    }
}

我能通过某种方式实现这一目标吗?

修改 此编辑旨在阐明情况和背景。请考虑下图。相同颜色的矩形意味着这些方法的实现是相同的。具有不同颜色的矩形意味着即使名称相同,实现也不同。我需要找到一种方法来实现classA和classB,但是没有重复的代码,并且仍然允许类" main"要知道classA和classB都有相同的方法名和变量。

Ilustrative figure

6 个答案:

答案 0 :(得分:1)

我首先想到的是,直截了当但不想要的实现将是SomeClass的两个子类,但实际上你想要的澄清。我仍然编辑了我的例子,以符合新旧版本的问题; - )

这个想法是将不同的实现隐藏到一组匿名类中,这些类实现了公共基类的抽象方法。基类是已知的,由runMethod1()和runMethod2()调用,使用的实现是在SomeClass的构造时决定的。

示例:

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();
    }
}

答案 1 :(得分:1)

一个班级无法实现这一目标。您应该查看工厂设计模式 - 为您的类提供一个接口,具有两个实现,并使用工厂根据您的参数生成所需的类 在此处查看更多详细信息:http://www.tutorialspoint.com/design_pattern/factory_pattern.htm

答案 2 :(得分:0)

您不能重载包含相同参数的方法 - 每个重载方法都必须包含不同的参数集。

看看你的第二个例子。 methodForAll可能只是runMethods(int),在其切换情况下,您可以根据提供的参数运行不同的方法。

在大多数情况下,为了达到这样的目的,你需要两个独立的类来实现一个接口或扩展一个类。

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);
    }

}

按预期输出:

Type1 - method()
Type2 - method()

答案 3 :(得分:0)

似乎你想要两个课而不是一个课! SomeClass应该由两个专门的类扩展。根据上下文,如果您有一些通用代码可以分解,它可以是接口或抽象类。由于您可能希望使用通用构造函数,因此抽象类似乎更合适。

答案 4 :(得分:0)

如果您要修复parameter并且不要将其作为方法调用者提供的参数,那么接口可能是一个解决方案:

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();

由于parameter在初始化类时已得到修复,因此您需要确定要初始化的类。

答案 5 :(得分:0)

我认为你无法实现它。使用相同的签名并且仅用于更改参数值,如果没有切换块,则无法调用不同的方法。

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]));
    }
}