【问题标题】:Java: alternative to global variables to pass values from methods to anotherJava:替代全局变量将值从方法传递到另一个
【发布时间】:2012-09-03 16:30:46
【问题描述】:

只是出于好奇!如果我有一个接受用户输入并将其存储为 int 变量的方法。有没有办法可以将这些方法传递给另一种方法?我知道返回值,但这只是(据我所知)一个数字、对象等......

最简单的方法当然是在这个方法中计算结果,但是是否有可能以某种方式传递这些整数:a,b。要另一种方法,而不使用全局变量?我只是想知道。

private void takeInput(int valueA, int valueB){
    println("Enter a number: (a) and (b), to calculate the Phytagoeran Theorem: (c)\n");
    int a = readInt("a:");
    println("you set the value of a to: "+a +"\n\nNext! set the value of b");
    int b = readInt("b:");
    println("you set the value of b to:"+b);
}

【问题讨论】:

  • 你在第一段和第二段中所说的有点混淆。那么,您想将variables 的值从一种方法传递到另一种方法吗?
  • 这并不是真正的 OOP 方式。您应该创建一个对象来保存所需的任何信息并将其传递。
  • 已经对您的问题“有没有办法可以将这些方法传递给另一种方法?”做出答复,我现在想知道您是否是这个意思?应该是“有没有办法可以将这些传递给另一个方法”?
  • @slim:是的,我最初的意思是这样,但得到了一个有趣的答案,关于如何将方法传递给另一个方法……我已经从 Obj-C 中知道了这一点。但是JAVA编程思想仍然是面向对象的。有时只是想得不太清楚。

标签: java methods parameter-passing


【解决方案1】:

这个问题不清楚,但我想知道你是否发明了“依赖注入”?

谜题的第一部分是,是的,一个方法可以返回多个值,方法是将它们包装在一个对象中。

public class ValuePair {
    public int a;
    public int b;
}

public ValuePair takeInput(){
  ValuePair pair = new ValuePair();
  println("Enter a number: (a) and (b)\n");
  pair.a = readInt("a:");
  pair.b = readInt("b:");
  return pair;
}

你可以这样做:

ValuePair p = takeInput();
System.out.println("Hypotenuse is " + calculateHypotenuse(p.a, p.b) + "\n";

(请注意,公共字段通常不被认为是好的样式 - 我在这里使用它们是因为代码更短。在实际代码中使用 getter 和 setter)。


这可能就是您需要的全部答案。但你问:

有没有办法可以将这些方法传递给另一个方法?

嗯,是的,如果您将该方法包装在一个专用的类中,您可以。出于我希望显而易见的原因,我们将首先定义一个接口。

 public interface ValuePairSource {
    public ValuePair getPair();
}

...以及实现它的类:

public class UserInputValuePairSource implements ValuePairSource {
    @Override
    public ValuePair getPair() {
         ValuePair pair = new ValuePair();
         println("Enter a number: (a) and (b)\n");
         pair.a = readInt("a:");
         pair.b = readInt("b:");
         return pair;
    }
}

现在您可以创建一个 Pythagoras 类,该类可以被告知从何处获取其值。

public class Pythagoras {
     private ValuePairSource valuePairSource;

     public Pythagoras(ValuePairSource source) {
         this.valuePairSource = source;
     }

     public double hypotenuse() {
         ValuePair pair = valuePairSource.getPair();
         return Math.sqrt(pair.a ^ 2 + pair.b ^ 2)
     }
}

在构造函数中,我们告诉我们创建的每个毕达哥拉斯对象,如何获取一对值。所以我们可以这样使用它:

Pythagoras p = new Pythagoras(new UserInputValuePairSource());
double hypotenuse = p.hypotenuse();

这有什么用?嗯,这意味着我们可以发明其他类型的 ValuePairSource。例如,一个 ShapeValuePairSource,它从我们设置的 Shape 对象中获取值。

(这些是出于问题目的的假设类)

所以你可以这样使用它:

Triangle t = canvas.getLastTriangle(); // or whatever
ValuePairSource vps = new ShapeValuePairSource(triangle);
Pythagoras p = new Pythagoras(vps);
double hypotenuse = p.hypotenuse();

因此,在完全不改变 Pythagoras 类的情况下,我们现在让它从形状对象中读取值,而不是用户输入。

好的,这是一个人为的例子,但它确实回答了“我可以将这些方法传递给另一个方法”的问题——这就是 Spring 之类的基础。

请注意,某些语言允许您将方法直接传递给其他方法,而无需像我们在这里那样将它们包装在一个类中。这称为“函数式编程”,通常将“方法”称为“函数”。

【讨论】:

    【解决方案2】:

    您可以创建一个包含 2 个值的类:

    public class PairOfInt {
        private final int a, b;
    
        public PairOfInt(int a, int b) {
           this.a = a;
           this.b = b;
        }
    
        //getters
    }
    
    
    private PairOfInt takeInput(){
        println("Enter a number: (a) and (b), to calculate the Phytagoeran Theorem: (c)\n");
        int a = readInt("a:");
        println("you set the value of a to: "+a +"\n\nNext! set the value of b");
        int b = readInt("b:");
        println("you set the value of b to:"+b);
        return new PairOfInt(a, b);
    }
    

    【讨论】:

    • 这就像为变量创建一个 getter & setter 方法?然后访问它的 getter 以从其他方法中获取变量的值?
    • 是的就是这个想法(在我的例子中只是一个吸气剂)
    【解决方案3】:

    你可以像这样声明另一个方法:

    private void doSomething(int a, int b) {
      ...
    }
    

    然后,从你的方法takeInput,你可以调用它:

    doSomething(a, b);
    

    【讨论】:

      【解决方案4】:

      您应该创建一个包含您想要操作的所有成员的类,并在同一个类中创建方法,这样您就不需要跨方法传递变量,也不需要依赖全局变量。

      class MyOperations {
      
          private int valueA;
          private int valueB;
      
          public MyOperations (int valueA, int valueB) {
            this.valueA = valueA;
            this.valueB = valueB;
          }
      
          public void doOperationA(){
          //
          }
      
          public void doOperationB(){
          //
          }
      
      }
      

      【讨论】:

        【解决方案5】:

        避免使用全局变量通常是个好主意。

        传递多个返回值主要有两种方式:

        1. 返回复合对象中的值
        2. 将值放入作为参数传递的对象中

        第一种方式涉及返回一个包含您要返回的所有值的对象。您可以使用已经可用的类,例如 Map 或 List:

        public List readIntegersFromInput() {
              List l = new ArrayList();
              l.add(readInt("a: "));
              l.add(readInt("b: "));
              return l;
        }
        

        ...或者您可以创建一个专门满足您需求的类:

        public class ValuesAandB {
            public int a;
            public int b;
        }
        

        ... 像这样使用:

        public ValuesAandB readIntegersFromInput() {
              ValuesAandB ab = new ValuesAandB;
              ab.a = readInt("a: ");
              ab.b = (readInt("b: ");
              return ab;
        }
        

        (在实际代码中,使用 setter 和 getter 代替公共字段)

        第二种方式涉及传递一个可变对象作为参数。可变对象是其值可以更改的对象——就像我们刚刚创建的 ValuesAandB 类。

        public void readIntegersFromInput(ValuesAandB ab) {
            ab.a = readInt("a: ");
            ab.b = (readInt("b: ");
        }
        

        ... 你可以这样称呼它:

        ValuesAandB values = new ValuesAandB();
        readIntegersFromInput(values);
        // use `values`
        

        那么哪个最好?您将在生产代码中看到这两种样式。现在普遍认为,在大多数情况下,第一种风格更可取。

        创建不可变的类实际上是个好主意,这是一个 ValuesAandB,您可以在其中设置构造函数中的值,然后再不允许更改它们。如果您需要不同的值,则必须创建一个新对象。您可以看到,对于不可变对象,第二种方式无法完成。它使代码更简洁,更易于理解。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-01-07
          • 1970-01-01
          • 1970-01-01
          • 2012-09-12
          • 2011-06-08
          • 2011-06-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多