【问题标题】:Java: How to call an integer value from an external methodJava:如何从外部方法调用整数值
【发布时间】:2021-01-26 07:18:09
【问题描述】:

我刚开始学习 java,所以我确定我只是缺少一些基本的东西。我必须创建一个 7 面的骰子对象,它会生成 1 到 7 之间的随机数:

import java.util.Random;
public class Dice {

      Random rand = new Random();
      int maxRoll = 7;

      public void roll(){
         int dicVal = rand.nextInt(maxRoll)+1; 
         }
  
   }

在那之后,我必须使用另一个文件从原始对象中制作 5 个不同的骰子,滚动它们,并检测天气是否它们滚动了相同的数字。

public class DiceRollem {
   public static void main (String[] args) {

      int turn=0;
      
      while (turn < 10) {
         turn ++;
         
      Dice dice1;
      dice1 = new Dice();
      dice1.roll();
      
      Dice dice2;
      dice2 = new Dice();
      dice2.roll();
      
      Dice dice3;
      dice3 = new Dice();
      dice3.roll();
      
      Dice dice4;
      dice4 = new Dice();
      dice4.roll();
      
      Dice dice5;
      dice5 = new Dice();
      dice5.roll();
      }
   }
}

我不确定如何从每个骰子中调用 dicVal 值以便比较它们。我能够在原始文件中编写一些可以返回值的内容,但是原始文件中不应该有返回值,而是应该全部在第二个文件中。同样,我确信这很容易,但看了之后我不知道该怎么做。

【问题讨论】:

  • 在循环之外创建骰子,您还必须在滚动函数中返回值以进行比较。
  • 将值作为字段存储在Dice 对象上。目前该值的范围仅限于roll方法
  • 让 roll() 方法返回一个 int 以便您可以存储它。我也会使用 Dice 对象数组,而不是使用单个变量。

标签: java methods integer


【解决方案1】:

你需要在方法内部设置一个属性,而不是一个变量。

public class Dice {
   // Set as static final because it doesn't change and is common to all dices
   private static final int maxRoll = 7;   

   // dicVal as property, not as local variable
   private int dicVal;

   private Random rand = new Random();

   // Added to set up a random value just after construction
   public Dice() {
      roll();    
   }

   public void roll() {
      // roll method set the property now
      dicVal = rand.nextInt(maxRoll)+1; 
   }


   // The public method to get the value
   public int getValue() {
      return dicVal;
   }

}

您可以按如下方式使用它:

 Dice dice1 = new Dice();
 System.out.println("The value is: " + dice1.getValue());
 dice1.roll(); // To change the value
 System.out.println("The new value is: " + dice1.getValue());
 ...
 

增强功能可以是创建一个骰子,在构造函数上声明它的大小,这样您就可以拥有 4、6、7(或任何您喜欢的)面的骰子。 只需将 maxRoll 声明为私有字段并在构造函数中进行如下设置:

public class EnhancedDice {
   private int maxRoll = 7;   
   private int dicVal;

   private Random rand = new Random();

   public EnhancedDice(int maxRoll) {
      this.maxRoll = maxRoll;
      roll();    
   }

   public void roll() {
      dicVal = rand.nextInt(maxRoll) + 1; 
   }


   public int getValue() {
      return dicVal;
   }

}

并按如下方式使用:

 EnhancedDice diceWith7sides = new EnhancedDice(7);
 System.out.println("The value is: " + diceWith7sides.getValue());
 diceWith7sides.roll(); // To change the value
 System.out.println("The new value is: " + diceWith7sides.getValue());
 ...
 EnhancedDice diceWith6sides = new EnhancedDice(6);
 System.out.println("The value is: " + diceWith6sides.getValue());
 diceWith6sides.roll(); // To change the value
 System.out.println("The new value is: " + diceWith6sides.getValue());
 ...

【讨论】:

  • @ScaryWombat 不,如果你想掷骰子而不是创建一个不可变的无用骰子。检查更新的答案,解释如何掷骰子来改变它的价值
【解决方案2】:

tl;博士

你每回合都在创造新的骰子。不。在我们正在建模的现实世界中,骰子不会在每次滚动后被丢弃。相同的物理骰子可重复用于多次掷骰。所以你的new Dice() 不应该在你的while (turn &lt; 10) {…} 里面。

  • 开始游戏时建立骰子集合。
  • 在每个回合中,遍历骰子集合,让每个骰子自行滚动。
  • 每个骰子都应该记住它的掷骰结果。 您的代码缺少此功能。 随着您的 roll 方法结束,int dicVal 蒸发,噗☁,消失了。您应该在该类上添加一个成员字段以记住 dicVal
  • 每次掷骰后,询问每个骰子的结果。

你问:

如何从每个骰子中调用 dicVal 值

首先将结果存储为类中成员字段的值。要稍后访问该值,请直接访问成员字段。为防止其他人更改该值,您可能希望将成员字段设置为 private,同时添加一个 getter 方法来返回其值。

详情

通常在面向对象的编程中,我们希望每个对象都能照顾好自己,并保持自己。

关于“照顾好自己”,每个骰子都应该跟踪其当前状态,即显示哪个面。在下面的示例代码中,Die 类带有一个成员字段 pips,用于表示其显示面上当前显示的点/标记的数量。

并且该类还包含一个成员字段,用于该特定骰子上的面数,在您的示例中为 7。请注意,此字段标记为final,因为它不会更改。相比之下,pips 字段在每掷骰子时都会发生变化。

关于“保持自己”,骰子的工作是了解其当前状态(点数)并滚动(更改其状态,以获得新的点数)。 不是模具的工作是参与管理它所参与的更大的游戏。游戏应该跟踪每个骰子;每个骰子都应该对游戏一无所知。游戏的工作是 (a) 要求每个骰子自己滚动,以及 (b) 询问每个骰子的当前状态(点数)。

package work.basil.example;

import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;

public class Die
{
    final private int faces; // How many faces (sides) does this die have.
    private int pips; // Number of pips (dots, marks) on the currently shown face.
    final private UUID id;

    public Die ( int faces )
    {
        this.faces = faces;
        this.id = UUID.randomUUID();
        this.roll();
    }

    // Logic
    public void roll ( )
    {
        this.pips = ThreadLocalRandom.current().nextInt( 1 , this.faces + 1 );
    }

    // Getters
    public int getPips ( )
    {
        return this.pips;
    }

    // Object methods


    @Override
    public String toString ( )
    {
        return "Die{ " +
                "faces=" + faces +
                " | pips=" + pips +
                " | id=" + id +
                " }";
    }
}

另一个类Game 调用该模具上的roll 方法。然后骰子在内部为显示的新点数生成随机数。 Game 对象对其收集的每个 Die 对象执行此操作。 Game 对象可以向每个 Die 对象询问其当前状态、当前点数。

你问:

我不确定如何从每个骰子中调用 dicVal 值以便比较它们

您的代码有问题。您将结果(新的点数)分配给名为 dicVal 的局部变量。但后来你的方法结束了。当该方法结束时,包括dicVal 在内的所有局部变量都将超出范围。这意味着 (a) 任何本地原始值(例如 int)都会立即消失,并且 (b) 任何本地对象引用(例如 Integer)都将被删除,从而使对象成为最终垃圾收集的候选对象(如果不存在对同一对象的其他引用)。因此,在确定骰子的新面值后,您立即丢弃该数字。

您需要将掷骰结果分配给持续时间更长的某个地方。理想的地方是同一类的成员字段。请注意,在上面的代码示例中,我们就是这样做的。掷骰子的结果存储在 Die 对象的 pips 类型 int 的私有字段中。

Game 对象的工作是首先收集所有骰子,然后检查每个骰子。 collection 部分是您缺少的另一部分。请注意,在下面的示例中,Game 对象如何保存 ListDie 对象。我们在Game 的构造函数中填充该列表。 Game 对象可以循环该列表中的 Die 对象,通过调用 getPips 来询问每个对象的当前状态。

package work.basil.example;

import java.util.ArrayList;
import java.util.List;

public class Game
{
    private List < Die > dice;

    public Game ( )
    {
        // Setup the game. Collect some dice to play.
        int countFacesOnEachDie = 7;
        int countDice = 5;
        this.dice = new ArrayList <>( countDice );
        for ( int nthDie = 1 ; nthDie <= countDice ; nthDie++ )
        {
            this.dice.add( new Die( countFacesOnEachDie ) );
        }
    }

    // Logic
    public void rollDice ( )
    {
        for ( Die die : dice )
        {
            die.roll();
        }
    }

    public String report ( )
    {
        int total = 0;
        for ( Die die : dice )
        {
            total = total + die.getPips();
        }
        String listing = this.dice.toString();
        String message = "Total: " + total + " = Dice: " + listing;
        return message;
    }

    // Main method (the app). Could be located in another class, such as `App` or `Main` is is likely in real work.
    public static void main ( String[] args )
    {
        Game game = new Game();
        int countTurns = 9;
        for ( int nthTurn = 1 ; nthTurn <= countTurns ; nthTurn++ )
        {
            game.rollDice();
            System.out.println( "Turn # " + nthTurn + " ➡ " + game.report() );
        }
    }
}

运行时。

Turn # 1 ➡ Total: 17 = Dice: [Die{ faces=7 | pips=1 | id=37c5c2ea-52d7-4e1f-a92c-7b99e0e7b70c }, Die{ faces=7 | pips=3 | id=58a724e6-a1a5-43d9-bc00-808c15a1980e }, Die{ faces=7 | pips=1 | id=db5557a5-8805-4f50-84a4-5d11eb1ec95a }, Die{ faces=7 | pips=6 | id=a61e5741-c56f-44d3-8222-073898da60bb }, Die{ faces=7 | pips=6 | id=0e96c3b6-5186-4323-bb26-dcfe99093a02 }]
Turn # 2 ➡ Total: 22 = Dice: [Die{ faces=7 | pips=5 | id=37c5c2ea-52d7-4e1f-a92c-7b99e0e7b70c }, Die{ faces=7 | pips=6 | id=58a724e6-a1a5-43d9-bc00-808c15a1980e }, Die{ faces=7 | pips=6 | id=db5557a5-8805-4f50-84a4-5d11eb1ec95a }, Die{ faces=7 | pips=3 | id=a61e5741-c56f-44d3-8222-073898da60bb }, Die{ faces=7 | pips=2 | id=0e96c3b6-5186-4323-bb26-dcfe99093a02 }]
Turn # 3 ➡ Total: 30 = Dice: [Die{ faces=7 | pips=6 | id=37c5c2ea-52d7-4e1f-a92c-7b99e0e7b70c }, Die{ faces=7 | pips=5 | id=58a724e6-a1a5-43d9-bc00-808c15a1980e }, Die{ faces=7 | pips=5 | id=db5557a5-8805-4f50-84a4-5d11eb1ec95a }, Die{ faces=7 | pips=7 | id=a61e5741-c56f-44d3-8222-073898da60bb }, Die{ faces=7 | pips=7 | id=0e96c3b6-5186-4323-bb26-dcfe99093a02 }]
Turn # 4 ➡ Total: 22 = Dice: [Die{ faces=7 | pips=2 | id=37c5c2ea-52d7-4e1f-a92c-7b99e0e7b70c }, Die{ faces=7 | pips=4 | id=58a724e6-a1a5-43d9-bc00-808c15a1980e }, Die{ faces=7 | pips=7 | id=db5557a5-8805-4f50-84a4-5d11eb1ec95a }, Die{ faces=7 | pips=4 | id=a61e5741-c56f-44d3-8222-073898da60bb }, Die{ faces=7 | pips=5 | id=0e96c3b6-5186-4323-bb26-dcfe99093a02 }]
Turn # 5 ➡ Total: 16 = Dice: [Die{ faces=7 | pips=6 | id=37c5c2ea-52d7-4e1f-a92c-7b99e0e7b70c }, Die{ faces=7 | pips=2 | id=58a724e6-a1a5-43d9-bc00-808c15a1980e }, Die{ faces=7 | pips=5 | id=db5557a5-8805-4f50-84a4-5d11eb1ec95a }, Die{ faces=7 | pips=1 | id=a61e5741-c56f-44d3-8222-073898da60bb }, Die{ faces=7 | pips=2 | id=0e96c3b6-5186-4323-bb26-dcfe99093a02 }]
Turn # 6 ➡ Total: 27 = Dice: [Die{ faces=7 | pips=4 | id=37c5c2ea-52d7-4e1f-a92c-7b99e0e7b70c }, Die{ faces=7 | pips=4 | id=58a724e6-a1a5-43d9-bc00-808c15a1980e }, Die{ faces=7 | pips=6 | id=db5557a5-8805-4f50-84a4-5d11eb1ec95a }, Die{ faces=7 | pips=7 | id=a61e5741-c56f-44d3-8222-073898da60bb }, Die{ faces=7 | pips=6 | id=0e96c3b6-5186-4323-bb26-dcfe99093a02 }]
Turn # 7 ➡ Total: 13 = Dice: [Die{ faces=7 | pips=1 | id=37c5c2ea-52d7-4e1f-a92c-7b99e0e7b70c }, Die{ faces=7 | pips=7 | id=58a724e6-a1a5-43d9-bc00-808c15a1980e }, Die{ faces=7 | pips=3 | id=db5557a5-8805-4f50-84a4-5d11eb1ec95a }, Die{ faces=7 | pips=1 | id=a61e5741-c56f-44d3-8222-073898da60bb }, Die{ faces=7 | pips=1 | id=0e96c3b6-5186-4323-bb26-dcfe99093a02 }]
Turn # 8 ➡ Total: 27 = Dice: [Die{ faces=7 | pips=7 | id=37c5c2ea-52d7-4e1f-a92c-7b99e0e7b70c }, Die{ faces=7 | pips=7 | id=58a724e6-a1a5-43d9-bc00-808c15a1980e }, Die{ faces=7 | pips=5 | id=db5557a5-8805-4f50-84a4-5d11eb1ec95a }, Die{ faces=7 | pips=3 | id=a61e5741-c56f-44d3-8222-073898da60bb }, Die{ faces=7 | pips=5 | id=0e96c3b6-5186-4323-bb26-dcfe99093a02 }]
Turn # 9 ➡ Total: 24 = Dice: [Die{ faces=7 | pips=2 | id=37c5c2ea-52d7-4e1f-a92c-7b99e0e7b70c }, Die{ faces=7 | pips=2 | id=58a724e6-a1a5-43d9-bc00-808c15a1980e }, Die{ faces=7 | pips=7 | id=db5557a5-8805-4f50-84a4-5d11eb1ec95a }, Die{ faces=7 | pips=6 | id=a61e5741-c56f-44d3-8222-073898da60bb }, Die{ faces=7 | pips=7 | id=0e96c3b6-5186-4323-bb26-dcfe99093a02 }]

提示:请注意我是如何为每个类和方法仔细选择名称的。我使用单数 Die 代表每个单独的部分。我使用复数 dice 作为集合 Die 对象的名称。我将每个骰子上显示的当前数字命名为pips 而不是dicVal,根据维基百科的正确术语。对于使用Die 对象的外部类,我选择了Game 而不是DiceRollem。专注于这些名称可以帮助您阐明您的设计。如果所有的名字看起来都很顺利,那可能是一个好的设计的标志。如果名称看起来笨拙或冲突,或缺乏明确的具体含义,则可能表明设计不佳。

【讨论】:

    猜你喜欢
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    • 2011-05-10
    • 2021-02-27
    • 1970-01-01
    相关资源
    最近更新 更多