如何扩展randomHuman构造函数以获取两种类型的对象?

时间:2014-11-08 15:34:10

标签: java class object constructor

我是一名java-noob,因为我最近开始在课程中学习。 我创建了一个课程:人类有能力存储他们的姓名和年龄,还有一个子类学生,它们扩展了人类并增加了他们开始学习的年份。 我构建了一个randomHuman构造函数,我在其中调用它(在我的主类中)并创建一个包含人类的列表(随机名称和年龄)。 我的问题是,当我想随机抽取5名非学生和5名学生并创建此列表时,我不知道如何找出哪种类型的对象被发送到随机构造函数,所以我知道我是否应该给它一个一年与否。什么类型告诉构造函数返回。

我很抱歉这变成了一篇文章,但如果有人愿意帮助那么我会非常感激。

TLDR; 如何扩展randomHuman构造函数以获取两种类型的对象?

这是我的主要课程:

  
    

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

  
Human newHuman = new Human( 18, "Tommy");
System.out.println("Age: " + newHuman.getAge());
System.out.println("Name: " + newHuman.getName());
System.out.println(newHuman.toString());

Human putte = new Human (25,"Putte");
System.out.println(putte);
//Varför blir det så?
//kanske lokal variabel

//Array RandomHumans
System.out.println(" ");
System.out.println("Array Human");
ArrayList<Human> myAl = new ArrayList();

for(int i = 0; i<15; i++){
    Human xx =Human.randomHuman();
    myAl.add(xx);
}
//Array RandomFysiker
for(int j = 0; j<myAl.size(); j++){
   Human var = myAl.get(j);
    System.out.println(var.toString());
}

System.out.println(" ");
System.out.println("Array Fysiker");
ArrayList<Fysiker> myAl2 = new ArrayList();
//puts the Fysiker in an array
for(int i = 0; i<15; i++){
    Fysiker xx =Fysiker.randomHuman();
    myAl2.add(xx);
}
//prints teh array
for(int j = 0; j<myAl2.size(); j++){
   Fysiker var = myAl2.get(j);
    System.out.println(var.toString());
}
     

}   }

和我的人类:

public class Human {
    public String name;
    public int age;

    Human(int ageIn, String nameIn){ //Constructor
    age=ageIn;
    name=nameIn;
    }
    public int getAge(){
        return age;
    }
    public String getName(){
        return name;
    }
    public String toString(){
        return "Name: " + getName() +"," + " Age: " + getAge();
    }


        //Random human
    // Behöver ändra konstruktorn så att den kan kolla
    // om objectet är Fysiker eller Human och sedan,
    // Behandla dom olika
    //Problem1: Hur kollar man? Föreslag if(obj instanceof Fysiker), men vad ska jag ha som obj
    //Problem2: Vilken returtyp ska man då ha?
    public static Human randomHuman(){
        String[] anArrayOfStrings={"Tom", "Jon", "Chris","Julian","Roberto","Sam","Lisa","Roxanne","Rebecca","Anton","Johannes","Antonella","Bianca"};
        int randomAge = (int) (100*Math.random());
        String randomName = anArrayOfStrings[(int)(Math.random()*anArrayOfStrings.length)];
        int RandomYear = (int) (Math.random()*(2013-1932) + 1932);
//        if(xx instanceof Fysiker){
//            
//        }
        return new Human(randomAge,randomName);
    }    
}

和子类Fysiker(又名学生):

/**
 *
 * @author Julian
 */

public class Fysiker extends Human{
    public int schoolYear;

    public Fysiker(int startYear,int ageIn, String nameIn){
        super(ageIn, nameIn);
        if (age>15){
            if (startYear>2013){
            } else if (startYear<1932){
            } else {
                schoolYear = startYear;
            }
        } else {
        }
    }
    public int getYear(){
        return schoolYear;
    }

    public String toString(){
        return super.toString() +","+" Startyear: " +getYear();
    }
}

3 个答案:

答案 0 :(得分:0)

要确定对象实例的类型,请使用object instanceof classobject.getClass().equals(Clazz.getSimpleName())

对于返回类型,只需使用superClass(或接口)。如果需要,您可以随时将其投射给孩子。

答案 1 :(得分:0)

如果你想创建5个类,你需要在方法声明中使用一个布尔值并且每次调用它5次,以确保每个类有5个实例。

    public static Human randomHuman(boolean isHuman){

如果这不重要,你可以添加一个随机布尔值,然后调用构造函数:

boolean isHuman = Math.random() < 0.5;
    if(!isHuman){
        int RandomYear = (int) (Math.random()*(2013-1932) + 1932);
        // create student
    } else {
        // create human
    }

答案 2 :(得分:0)

实际上,评论中提到的randomHuman()方法根本不是构造函数。这是一种静态的工厂方法,虽然我确定你还没有意识到这意味着什么。

基本上,构造函数根本不是一个方法,并且没有返回类型。构造函数的作用是为使用new创建的类的新实例提供初始化,尽管它可以执行不严格启动该对象字段的操作。

相反,一种方法可以返回一些东西。在您的特定情况下,最后一行实际上会告诉您它返回的确切内容 - 它正在为类new调用Human,因此它将返回类Human的对象,而不是{ {1}}。

事实上,班级Student不了解班级Human。原则上,您可以在编写父类之后的几年内为类编写子类。家长班不需要了解他们的后代。他们只是决定他们允许这些后代改变什么,以及他们不允许他们改变什么。

理论上,您可以在Student中创建一个创建Human实例的方法。但我很确定在目前的情况下不需要。

您可能想要做的是填写StudentHuman定义之外的人员列表。填写随机列表可能不是“成为一个人”或“成为学生”的一部分,所以你应该在Student课程中进行,调用Main或{{1}如你所愿,并酌情填写。既然你知道你调用了哪个new Human(),你也知道是否使用随机年份。

您可以在new Student()类中使用静态方法执行此操作,以表示这是您为测试所做的事情,而不是new或{{Main逻辑的一部分。 1}}。

至于能够告诉您现在从列表中获得哪个对象 - 您可以使用Human执行此操作。但是,如果要访问其Student方法,还需要将其强制转换为instanceof

然而 - 这是关于多态的巧妙之处 - 如果你只是调用Student方法,甚至不检查对象的类型,如果它真的是一年,你会得到它的年份getYear()对象,如果它是普通的toString()对象,则没有它。


我们假设您的教师实际上希望您扩展Student方法,以便它有时会提供Human个实例,有时会提供randomHuman。当它给出Human时,它当然应该提供一年。

如上所述,这在父类和子类之间称为紧耦合,不推荐使用。如果我想构建另一个人类子类,例如Students,我必须打电话给你,并要求你发布一个新版本的Student,有时也会提供随机Politician。所以,在抗议之下,我会解释如何去做。

您现有的职能是:

Human

我们改变它:

Politician

因此,您决定要创建一个普通的人,并且在该决定的范围内,您使用public static Human randomHuman(){ String[] anArrayOfStrings={"Tom", "Jon", "Chris","Julian","Roberto","Sam","Lisa","Roxanne","Rebecca","Anton","Johannes","Antonella","Bianca"}; int randomAge = (int) (100*Math.random()); String randomName = anArrayOfStrings[(int)(Math.random()*anArrayOfStrings.length)]; int RandomYear = (int) (Math.random()*(2013-1932) + 1932); // if(xx instanceof Fysiker){ // // } return new Human(randomAge,randomName); } 创建它并分配给public static Human randomHuman(){ String[] anArrayOfStrings={"Tom", "Jon", "Chris","Julian","Roberto","Sam","Lisa","Roxanne","Rebecca","Anton","Johannes","Antonella","Bianca"}; int randomAge = (int) (100*Math.random()); String randomName = anArrayOfStrings[(int)(Math.random()*anArrayOfStrings.length)]; Human result = null; if ( Math.random() < 0.5 ) { // With a probability of 50%, create a plain human result = new Human( randomAge, randomName ); } else { // Create a student. Start by calculating a random year. int randomYear = (int) (Math.random()*(2013-1932) + 1932); result = new Fysiker( randomYear, randomAge, randomName ); } return result; } 变量。

如果您决定让学生在该决定的范围内,您计算一个随机年份,并使用new Human(...)创建。您可以将其分配给变量result,因为它是多态的,new Fysiker()。但实际上,在内部,它是学生。

您返回result变量,此时可能包含Humanresult