【问题标题】:Using varargs to create an object in a class [closed]使用可变参数在类中创建对象 [关闭]
【发布时间】:2021-05-16 19:40:05
【问题描述】:

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

如何在类中设置这样的对象?构造函数必须使用可变参数,因为 Power 可以有不同的参数。这是我的尝试,但显然是行不通的! 这是过去 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;
    
    }
}

【问题讨论】:

标签: java class constructor arguments variadic-functions


【解决方案1】:

你的代码有很多困难:

  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{
        
    }
}

【讨论】:

    【解决方案2】:

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

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

    为了简单起见,让我们使用 Java 16 中的 Record 特性。编译器隐式创建构造函数、getter、equals & hashCodetoString。当类的主要目的是透明和不可变地携带数据时,记录是合适的。使用记录使这个示例代码更短。

    package work.basil.example.Game;
    
    import java.util.Set;
    
    public record GameCharacter (String name, Set <Power> powers)
    {
    }
    

    对于不可修改的Set,使用Set.of 方法。

    package work.basil.example.Game;
    
    public record Power(String description)
    {
    }
    
    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 &lt; Power &gt; 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 对象的数组到达。我们可以使用 for-each 语法循环该数组的元素。我们将每个元素添加到我们选择的新 Set 实现中,在本例中为 HashSet 类。

        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;
        }
    

    为了使用这个构造函数,我们调整了 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 , 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 + ']';
        }
    }
    

    提示:如果您希望您的成员字段 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.
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-27
      • 1970-01-01
      • 2021-12-11
      相关资源
      最近更新 更多