使用可变参数在类中创建对象

问题描述

我正在尝试创建一个名为 GameCharacter 的类,它代表一个游戏角色并具有 以下属性: • 名称(字符串) • powers(一组 Power 对象)

如何在类中设置这样的对象?构造函数必须使用可变参数,因为 Powers 可以有不同的参数。这是我的尝试,但显然是行不通的! 这是来自过去的 2019 年作业问题,我没有解决方案,而且我是 Java 的初学者。感谢任何帮助理解这一点!

    class GameCharacter{
    private String name;
    private int cost;
    class Powers{
        public Powers(Power... powers) {
            for (int i: powers) {
                this.i = powers
                
            }
        }
    }
    
    //constructor
    public GameCharacter(String name,int cost,Power... powers) {
        this.name = name;
    
    }
}

解决方法

你的代码有很多困难:

  1. 错误的 foreach 声明。
  2. 不同的类型和方法参数名称。
  3. 在类 Powers 中缺少类型 Power 的字段。

我猜你可能想做什么,但你的问题需要适度。

class GameCharacter{

    private String name;

    private int cost;

    class Powers{
        
        public Powers(Power... powers) {
            for (Power i: powers) {
                //what initialize do you want?  
            }
        }
    }

    //constructor
    public GameCharacter(String name,int cost,Powers powers) {
        this.name = name;    
    }
    
    class Power{
        
    }
}
,

对于一组 Set < Power > 对象,使用 Power

如果要跟踪一组 Set 对象,请使用 Set 类。不需要可变参数,只需传递一个 Record 对象。

为了简单起见,让我们使用 Java 16 中的 equals 特性。编译器隐式地创建构造函数、getter、hashCode & toStringpackage work.basil.example.Game; import java.util.Set; public record GameCharacter (String name,Set <Power> powers) { } .当类的主要目的是透明和不可变地携带数据时,记录是合适的。使用记录可以让这个示例代码更短。

Set

对于不可修改的 package work.basil.example.Game; public record Power(String description) { } ,使用 Set.of 方法。

package work.basil.example.Game;

import java.util.Set;

public class App
{
    public static void main ( String[] args )
    {
        App app = new App();
        app.demo();
    }

    private void demo ( )
    {
        GameCharacter susan = new GameCharacter(
                "Susan",Set.of(
                        new Power( "invisibility" ),new Power( "force field" )
                )
        );
        GameCharacter ben = new GameCharacter(
                "Ben",Set.of(
                        new Power( "physical strength" ),new Power( "rock-like hide" )
                )
        );

        System.out.println( "susan = " + susan );
        System.out.println( "ben = " + ben );
    }
}
susan = GameCharacter[name=Susan,powers=[Power[description=force field],Power[description=invisibility]]]
ben = GameCharacter[name=Ben,powers=[Power[description=rock-like hide],Power[description=physical strength]]]

运行时:

record

如果您要定义常规类而不是 GameCharacter,您将在 String 类上定义两个成员字段:Set < Power > powers 用于名称,Power 用于集合package work.basil.example.Game; import java.util.Objects; import java.util.Set; public final class GameCharacter { // Member fields private final String name; private final Set < Power > powers; // Constructor public GameCharacter ( String name,Set < Power > powers ) { this.name = name; this.powers = powers; } public String name ( ) { return name; } public Set < Power > powers ( ) { return powers; } @Override public boolean equals ( Object obj ) { if ( obj == this ) return true; if ( obj == null || obj.getClass() != this.getClass() ) return false; var that = ( GameCharacter ) obj; return Objects.equals( this.name,that.name ) && Objects.equals( this.powers,that.powers ); } @Override public int hashCode ( ) { return Objects.hash( name,powers ); } @Override public String toString ( ) { return "GameCharacter[" + "name=" + name + "," + "powers=" + powers + ']'; } } 个对象。你会为这两个字段添加一个带有两个参数的构造函数。

Power

可变参数

现在我们可以回到您的具体问题:如何在构造函数中处理可变参数。

这里我们为上面看到的类添加了第二个构造函数。第二个采用 Power 类型的可变参数。

可变参数作为 Set 对象数组到达。我们可以使用 for-each 语法循环该数组的元素。我们将每个元素添加到我们选择的新 public GameCharacter ( String name,Power... powers ) { this.name = name; Set<Power> s = new HashSet <>(); // New empty `Set` implementation. for ( Power power : powers ) // `powers` is the varargs array of `Power` objects. { s.add(power); // Add each element of array,each `Power` object,to our `Set` collection. } this.powers = s; } 实现中,在本例中为 HashSet 类。

App

为了使用这个构造函数,我们调整了 Set.of 类以放弃对 package work.basil.example.Game; import java.util.Set; public class App { public static void main ( String[] args ) { App app = new App(); app.demo(); } private void demo ( ) { GameCharacter susan = new GameCharacter( "Susan",new Power( "invisibility" ),new Power( "force field" ) ); GameCharacter ben = new GameCharacter( "Ben",new Power( "physical strength" ),new Power( "rock-like hide" ) ); System.out.println( "susan = " + susan ); System.out.println( "ben = " + ben ); } } 的调用。

GameCharacter

这是我们修改后的 package work.basil.example.Game; import java.util.HashSet; import java.util.Objects; import java.util.Set; public final class GameCharacter { // Member fields private final String name; private final Set < Power > powers; // Constructors // First constructor public GameCharacter ( String name,Set < Power > powers ) { this.name = name; this.powers = powers; } // Second constructor public GameCharacter ( String name,Power... powers ) { this.name = name; Set<Power> s = new HashSet <>(); for ( Power power : powers ) { s.add(power); } this.powers = s; } // Getters public String name ( ) { return name; } public Set < Power > powers ( ) { return powers; } // `Object` overrides @Override public boolean equals ( Object obj ) { if ( obj == this ) return true; if ( obj == null || obj.getClass() != this.getClass() ) return false; var that = ( GameCharacter ) obj; return Objects.equals( this.name," + "powers=" + powers + ']'; } } 的整个类的源代码,现在提供两个构造函数。

powers

提示:如果您希望您的成员字段 // Second constructor public GameCharacter ( String name,Power... powers ) { this.name = name; this.powers = Set.of( powers ) ; // Make an unmodifiable set from the varargs array. } 是一个不可修改的集合,您可以将第二个构造函数简化为:

{{1}}