Java 以不同的方式重用相同的函数

Java 以不同的方式重用相同的函数,java,Java,我有这样的课 class Calculate { int operation(int a, int b){ return Math.max(a,b); } int calc(int a, int b){ int x=100+a*b; int y=a+a*b; retun operation(x,y); } int calc1(int a, int b){ int x=100+

我有这样的课

class Calculate {
    int operation(int a, int b){
         return Math.max(a,b);
    }
    int calc(int a, int b){
        int x=100+a*b;
        int y=a+a*b;
        retun operation(x,y);
    }
    int calc1(int a, int b){
        int x=100+a*b;
        int y=b+a*b;
        return operation(x,y);
    }
}
现在我将这个类的两个对象设置为
Calculate obj1=新计算()
Calculate obj2=new Calculate()
我希望calculate类的函数操作类似于为obj1返回两个最大值,为obj2返回两个最小值。这能做到吗

我只能想到创建两个不同的类Calculate1和Calculate2,并在Calculate1中将运算定义为最大值,在Calculate2中将运算定义为最小值,并将其余的东西定义为和它一样。我希望在不定义两个类的情况下也存在一些更简单的方法。

您可以如下修改您的类:

class Calculate {
    private boolean calcMax;

    public Calculate(boolean calcMax){
        this.calcMax = calcMax;
    }

    int operation(int a, int b){
         return calcMax ? Math.max(a,b) : Math.min(a,b);
    }
}

您可以覆盖
操作
方法

如果不想创建显式子类,可以使用匿名类:

Calculate obj1=new Calculate();
Calculate obj2=new Calculate() {
    int operation(int a, int b){
        return Math.min(a,b);
    }
};

obj1.operation(a,b) // calculates maximum
obj2.operation(a,b) // calculates minimum

您可以将操作传递给构造函数,例如:

class Calculate {

  private final IntBinaryOperator op;

  public Calculate(IntBinaryOperator operator) {
    this.op = operator;
  }

  int operation(int a, int b) {
    return op.applyAsInt(a, b);
  }
}
现在你可以写:

Calculate c1 = new Calculate(Math::max);
Calculate c2 = new Calculate(Math::min);
添加一个操作很简单-假设您想要的是和,而不是最小值或最大值:

Calculate c3 = new Calculate((x, y) -> x + y);

您可以使用名为继承的OOP概念

public abstract class Calculate {

    public abstract int operation(int a, int b);

    int calc(int a, int b){
        int x=100+a*b;
        int y=a+a*b;
        return operation(x,y);
    }

    int calc1(int a, int b){
        int x=100+a*b;
        int y=b+a*b;
        return operation(x,y);
    }

}

class Obj1 extends Calculate{

    @Override
    public int operation(int a, int b) {
        return Math.min(a, b);
    }

}

class Obj2 extends Calculate{

    @Override
    public int operation(int a, int b) {
        return Math.max(a, b);
    }

}

每个新类都实现它自己的操作方法。

您可以有如下内容:

interface Operation
{
    int operation(int a,int b);
}
class Calculate
{
    Operation operation;
    //rest of class
}
Calculate obj1=new Calculate();
obj1.operation=(a,b)->Math.max(a,b);
Calculate obj2=new Calculate();
obj2.operation=(a,b)->Math.max(a,b);
Calculate obj1=new Calculate();
obj1.operation=new Operation{
                   @Override
                   int operation(int a,int b)
                   {
                       return Math.max(a,b);
                   }
               }
//code for obj2
您可以这样使用该类:

interface Operation
{
    int operation(int a,int b);
}
class Calculate
{
    Operation operation;
    //rest of class
}
Calculate obj1=new Calculate();
obj1.operation=(a,b)->Math.max(a,b);
Calculate obj2=new Calculate();
obj2.operation=(a,b)->Math.max(a,b);
Calculate obj1=new Calculate();
obj1.operation=new Operation{
                   @Override
                   int operation(int a,int b)
                   {
                       return Math.max(a,b);
                   }
               }
//code for obj2
几点注意:
  • 您可以添加一个构造函数,该构造函数采用
    操作
    来初始化
    操作
    变量
  • 您可能应该在
    Calculate
    类中有一个
    call
    方法,并将
    操作设置为private,以便更好地封装
  • 操作
    最好是最终操作
  • 这个解决方案可能没有其他语言那么简单,但它是我能拥有的最好的解决方案。
    从一开始就支持作为第一类公民的函数的语言会使这变得更容易,因为您可以像任何变量一样拥有一个赋值、传递和返回的函数变量 在java中,我们必须使用接口和匿名类来支持这一点,上面的lambda表达式被添加到java 8中,因此对于java 7,我们将这样编写上面的内容:

    interface Operation
    {
        int operation(int a,int b);
    }
    class Calculate
    {
        Operation operation;
        //rest of class
    }
    
    Calculate obj1=new Calculate();
    obj1.operation=(a,b)->Math.max(a,b);
    Calculate obj2=new Calculate();
    obj2.operation=(a,b)->Math.max(a,b);
    
    Calculate obj1=new Calculate();
    obj1.operation=new Operation{
                       @Override
                       int operation(int a,int b)
                       {
                           return Math.max(a,b);
                       }
                   }
    //code for obj2
    
    编辑 您可以将
    操作
    替换为java 8中引入的操作(特别是
    IntBinaryOperator
    )。

    您可以使用它来实现您的目标

    基本上,您希望将
    操作
    外部化到一个接口,并在
    计算
    的构造函数中指定实现该接口的对象(使用最小值或最大值)

    这种方法为您提供了最灵活的解决方案,可以证明需求的变化

    public class Calculate {
    
    public int a=0;
    public int b=0;
    
    public int maxVal = 0;
    public int minVal = 0; 
    
    public Calculate(int a, int b){
        this.a=a;
        this.b=b;
    
        this.maxVal=Math.max(a,b);
    
    
        this.minVal = Math.min(a, b);
    
    }
    }
    

    假设您正在查找相同变量的mins和max…

    hmm在其他语言中,您可能会有一个“函数对象”(C#中的委托,C中的函数指针,python中的函数变量,ruby,haskell),在java中,我会寻找一个接口和匿名类。您能为给定的示例代码提供经过编辑的代码吗?“那太好了!”niceman Java在1.8中添加。这将通过初始化全局变量来完成工作。但同样的工作也可以通过面向对象的概念来完成(不使用全局变量)?这在OP的例子中效果很好,因为他的其他方法引用了
    操作
    ,而该操作也将使用重写的方法。这可能会更优雅,或者至少是对称的,使操作抽象。这可能会。这似乎要视情况而定。假设计算对象的标准是找到最大值,并且程序中有许多计算对象。如果出于某种原因,一个计算对象需要成为该规则的例外,Eran的答案更合适。如果该方法根本没有标准,那么将该方法抽象化会更好。如果类没有标准,那么整个计算类将是抽象的,子类应该执行各种操作。这不是抽象。这是继承。抽象是将复杂代码隐藏在当前范围之外的概念,这样类就不需要或不关心其他类如何工作。OP说“我只能考虑定义两个类”,所以OP显然想避免创建类:)我想他只是不想重复相同的代码(方法calc和calc1)在两个不同的类别中,这是策略pattern@OlegKurbatov是的,在我看到你的答案后,我发现了这一点,因此我投了赞成票:)