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是的,在我看到你的答案后,我发现了这一点,因此我投了赞成票:)