【问题标题】:Different arguments in function函数中的不同参数
【发布时间】:2016-10-29 14:05:44
【问题描述】:

例如,我有一个类 X,它有两个名为 ex 的字段。 aField 和 bField。在主类中,我得到了对象类 X 的表和应该调用的函数,但在第一次它必须更改名为 aField 的字段,在第二次调用中必须更改名为 bField 的字段。

class X{
    int aField;
    int bField;
}
class Main{
    public X[] listX;
    public int amount;
    public static void requestedFunction(){
        for(int i=0; i<amount; i++){
            aField = 5;
            // bField = 5; 
            // or this one when called second time in code ;
        }

    }
    public static void main(String[] args) {
        amount = 10;
        listX= new X[amount];

        requestedFunction(); // thsi usage change fields named aFields
        requestedFunction(); // this usage change fields named bFields
    }
}

有没有办法以这种方式做到这一点?或者我需要制作 2 个不同的功能?

【问题讨论】:

  • 你可以重载一个方法。
  • 但还是同类型的变量。
  • 你的评论说当调用一个第二个参数

标签: java function arguments


【解决方案1】:

从技术上讲,您可以通过以下方式实现这一目标

enum ExecutionType {
    ATYPE,
    BTYPE
}

public static void requestedFunction(ExecutionType eType){
    for(int i=0; i<amount; i++){
        if (eType==ExecutionType.ATYPE)
            aField = 5;
        else if (eType ==ExecutionType.BTYPE)
            bField = 5; 
    }
}

requestedFunction(ExecutionType.ATYPE);
requestedFunction(ExecutionType.BTYPE);

但是,实现此目的的正确方法是使用两个单独的函数。这种设计不是很好,并且有可能在更复杂的场景中引起严重的头痛。

不使用参数的版本也是可能的,但它违反了越来越多的面向对象的原则。每次调用时执行不同操作的函数的行为很难理解。

【讨论】:

  • 我会更进一步,大声指出:虽然在技术上是可行的,但这种风格真的很糟糕,将来会导致问题。枚举应该以这种方式使用。
【解决方案2】:

您可以使用reflection 做到这一点。该库允许您使用纯粹基于“字符串”的类/字段。使用相应的库,您本质上可以编写一个方法,例如

public void putValue(X instanceOfX, int value, String fieldName)

然后这样称呼

putValue(x, 5, "fieldA");

但是:你最好不要那样做!反射很复杂,而且容易出错!而且它一点也不健壮,当您决定稍后重命名字段时,您只会在 运行时 注意到您的 putValue() 方法被调用时使用过时的字段名称。

另一种方法是使用地图,例如:

Map<String, Integer> theValues = new HashMap<>();

所以你可以编写如下代码:

theValues.put("A", 5);
theValues.put("B", 5);

但真正的答案在这里:退后一步,看看你真正想要解决的问题。你看,使用允许将 A 类写入 B 类的字段已经是一个坏主意。好的 OO 设计的整个想法是公开此类实现细节。字段是实现细节,只有拥有的类应该知道这些字段。

良好的 OO 是将行为放入您的课程中。含义:您的 X 类不应提供其他类读取/写入的字段。相反,该类应该具有为其他方法“做这些事情”的方法(请注意:我不是在谈论用 getter/setter 方法替换字段访问!)。

【讨论】:

    【解决方案3】:

    您还可以传递消费者并决定要修改哪个字段。 这是一个小例子:

    public class Test {
    
    private static Product[] products;
    
    public static void main(String[] args) {
        doSomething((p) -> p.setName("CLOTHING")); //first loop
        doSomething((p) -> p.setId(1)); //second loop
    }
    
    public static void doSomething(Consumer<Product> productConsumer){
        products = getProducts();
        for(Product p : products){
            productConsumer.accept(p);
            System.out.println(p.toString());
        }
    
    }
    
    private static Product[] getProducts(){
        Product pr1 = new Product();
        pr1.setId(1);
        pr1.setName("Jacket");
    
        Product p2 = new Product();
        p2.setId(2);
        p2.setName("Shoe");
    
        return new Product[]{pr1, p2};
    }
    
    }
    
    public class Product {
    
    private int id;
    private String name;
    }
    

    【讨论】:

      猜你喜欢
      • 2021-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-21
      • 2021-02-18
      • 1970-01-01
      • 2019-08-02
      • 2013-05-22
      相关资源
      最近更新 更多