如何使用Java中同一类中的另一个setter为setter赋值

时间:2014-08-09 03:40:51

标签: java getter-setter

我是编程新手,我正在制作基于文本的游戏;更具体地说,是玩家创造。它会要求您声明人名,性别和类型(青少年,年轻成人,成年人或老年人),并根据玩家类型给出该人的年龄,例如:青少年可能是13-17岁。为此,我询问用户类型是什么,这将是setPlayerType的值。然后,setAge假设使用setPersonType中的信息来决定使用if语句的年龄。要测试程序以查看播放器创建系统是否有效,我将其打印出名称,播放器的年龄和性别。但是,它始终打印年龄为0,我一直试图修复它近一个小时。对不起,如果我没有使用正确的命名约定,我仍然试图获得setter和getters的支持。我希望我能够很好地解释这一点,让你们明白我要做的事情。非常感谢你!

这是我的测试人员课程:

import javax.swing.JOptionPane;

    public class PopulationGameTestDrive {

        static Person one = new Person();



        public static void main(String[] args){

            one.setName(JOptionPane.showInputDialog("Name your player"));
            one.setGender(JOptionPane.showInputDialog("What is their gender?"));
            one.setPersonType(JOptionPane.showInputDialog("Are they a teen, young adult, adult, or elder?"));

            String testName = one.getName();
            String testGender = one.getGender();
            int testAge = one.getAge();

            System.out.println(testName + " is " + testAge + " and is a " + testGender);

        }

    }

这是Player类:

import java.util.Random;

public class Person {

    private String name; //they choose a name
    private String gender; //male or female
    private String personsType; //teen, young adult, adult, or elder
    int numOfKids = 0;
    private int age;

    public String getName(){
        return name;
    }

    public void setName(String personsName){
        name = personsName;
    }

    public String getPersonType(){
        return personsType;
    }

    /*
     * setPersonType gives age a value based on whether
     * the player chose teen, young adult, adult, or elder
     */
    public void setPersonType(String personType){
        personsType = personType;
    }



    public String getGender(){
        return gender;
    }

    public void setGender(String personsGender){
        gender = personsGender;
    }

    public int getAge(){
        return age;
    }

    public void setAge(int personsAge){
        if(personsType.equals("teen")){
            Random num = new Random();
            int number = num.nextInt(20);
            if(number > 12 & number < 18){
                age = number;
            } else if(personsType.equals("young adult")){
                Random num2 = new Random();
                int number2 = num2.nextInt(30);
                if(number2 > 17 & number2 < 31){
                    age = number2;
                } else if(personsType.equals("adult")){
                    Random num3 = new Random();
                    int number3 = num3.nextInt(50);
                    if(number3 > 30 & number3 < 50){
                        age = number3;
                    }else if(personsType.equals("elder")){
                        Random num4 = new Random();
                        int number4 = num4.nextInt(100);
                        if(number4 > 49 & number4 < 101){
                            age = number4;
                        }
                    }
                }
            }
        }
        age = personsAge;
    }

}

5 个答案:

答案 0 :(得分:1)

Mshnik是正确的,你的测试类实际上从不实际调用setAge(int),并且对于使用一组有限的可接受值来表示数据容易出错的字符串有好处。但是,即使您在测试类中调用setAge()甚至将personType转换为枚举,您的setter中也会遇到其他一些正确性和健壮性问题。既然你提到仍然试图抓住它们,我想借此机会提一下在突然出现不同意外行为之前跳到我身上的内容。

当你有将对象作为参数的setter时,你必须始终确保它们以可接受的方式处理参数null。

正如您的代码所代表的那样,如果用户关闭任何输入对话框,则在调用equals()时将抛出NullPointerException,并且在开发游戏时,堆栈跟踪将不必要地进行调试。您应该决定是否可以合理地将每个字段设置为null,如果没有,则setter抛出IllegalArgumentException并在调用setter的代码中正确处理它。

其次,考虑用户是否输入&#34; TEEN&#34;作为年龄段。您的代码不会按照预期将年龄设置为青少年范围内的随机值,它会将年龄设置为传递给setAge()的值,我假设这是一个默认值,可能与他们的理性不相关类型。在将用户输入的字符串与存储的值进行比较时,使用equalsIgnoreCase()是更好的做法。

第三,随着人口游戏中时间的流逝,年龄被初始化后,setAge()会被调用吗?这是int参数的目的吗?如果是这样,你仍会得到意想不到的结果,例如青少年玩家为15,调用setAge(16),变量实际上设置为14。

我对如何避免这个问题的理解归结为两条路径之一。您可以将setAge(int)的实现更改为仅在以前未初始化age时使用随机值,否则将age设置为其参数。例如,调用setAge的逻辑还需要确保在青少年年满20岁时更新类型。

这要求setter执行至少两个单独的作业,因此我的要求是,在您修改测试时,在Person中重载setAge是很有价值的。我使用一个带有整数参数的函数来检查一个合理的参数值,然后设置变量,另一个带有AgeBracket枚举参数,该参数使用现有的实现将变量设置为括号内的随机int值。

答案 1 :(得分:0)

我不确定你的main方法在任何时候实际上都调用了setAge(..)。所以getAge()返回0的原因是因为0是整数的默认值。 (你永远不会改变)

即使调用了setAge(..),逻辑也可能不会完全按照您的想法执行。你有一个非常详细的if块,它根据人的类型为年龄分配不同的值。在那之后,无论是否执行if块,age都设置为personsAge,使整个if块无用。也许最后的陈述应该是在其他分支中?

你的setAge()函数的逻辑并不完全正确:personsType.equals("young adult")的else-if分支与if(number > 12 & number < 18)配对,而不是if(personsType.equals("teen"))。所以我相信第一个else-if分支永远不会被执行,因为它包含在if(personsType.equals("teen"))中,如果没有personType更改,这将在if分支中始终为false。考虑一下你的setAge()函数的这个版本,我相信它可以达到你所希望的更接近的逻辑:

根据您的评论,不要使用设置约定,因为您要设置为随机值,而不是给定值。另外,出于调试目的,请尝试使用此代码,该代码包含一些打印语句。

public void setRandomAge(){
    System.out.println(personsType); //The type of this person, for debugging purposes to 
                                     //make sure it's valid at this point
    if(personsType.equals("teen")){
        age = (int)(Math.random() * 4) + 13); //random number between [13,17], inclusive
    } 
    else if(personsType.equals("young adult")){
        age = (int)(Math.random() * 12) + 18; //random number between [18,30], inclusive
    }
    else if(personsType.equals("adult")){
        age = (int)(Math.random() * 18) + 31; //random number between [31, 49], inclusive
    }
    else if(personsType.equals("elder")){
        age = (int)(Math.random() * 50) + 50; //random number between [50, 100], inclusive
    }
    else{
        age = 0; //Probably should have some default case for 
                 //if the personsType is some other string
   }
}

我也同意Sparrow - 在setPersonType方法中添加对此方法的调用是一个好主意:

public void setPersonType(String personType){
    personsType = personType;
    setRandomAge();
}

最后,既然你是新手,那么请注意你应该考虑为personType使用字符串为personType制作Enum是笨重且容易出错的。

答案 2 :(得分:0)

您没有尝试在测试人员课程中设置年龄。

获取年龄,因为它将是字符串,然后将其转换为int。

找到代码段

String ageString = JOptionPane.showInputDialog("What is your Age?")

try {
   int age = Integer.parseInt(ageString);

    one.setAge(age);
} catch (NumberFormatException e) {
  // Not a number, display error message if entered string is not a valid age...

}

答案 3 :(得分:0)

你不需要在setAge(...)中传递任何参数 它应该是这样的:

public void setAge(){
    if(personsType.equals("teen")){
        Random num = new Random();
        int number = num.nextInt(20);
        if(number > 12 & number < 18){
            age = number;
        } else if(personsType.equals("young adult")){
            Random num2 = new Random();
            int number2 = num2.nextInt(30);
            if(number2 > 17 & number2 < 31){
                age = number2;
            } else if(personsType.equals("adult")){
                Random num3 = new Random();
                int number3 = num3.nextInt(50);
                if(number3 > 30 & number3 < 50){
                    age = number3;
                }else if(personsType.equals("elder")){
                    Random num4 = new Random();
                    int number4 = num4.nextInt(100);
                    if(number4 > 49 & number4 < 101){
                        age = number4;
                    }
                }
            }
        }
    }
}

这个方法应该在setPersonType(...)的main或者末尾调用:

public void setPersonType(String personType){
    personsType = personType;
    setAge();
}

答案 4 :(得分:0)

如果我使用这个问题的主题,那么答案就是:

class Person {
  int age;
  String personType;

  void setAge(int age) {
    this.age = age;
  }

  void calculateRandomAge() {
    Random rand = new Random();
    if(personsType.equals("teen")){
        int number = rand.nextInt(6);
        setAge(number+12);
    } else if(personsType.equals("young adult")){
        int number = rand.nextInt(14);
        this.setAge(number+17);
    } ...

(你没有描述这个方法应该实际做什么,所以我只是说明你如何在自己的情况下调用一个setter?#34。你通常不会使用this.,但我曾经使用过一次图示。