使用可变参数在 class 中创建对象
Using varargs to create an object in a class
我正在尝试创建一个名为 GameCharacter 的 class,它代表一个游戏角色并且具有
以下属性:
• 名称(字符串)
• 权力(一组权力对象)
如何在 class 中设置这样的对象?构造函数必须使用可变参数,因为 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;
}
}
你的代码有很多难点:
- 错误的
foreach
声明。
- 不同的类型和方法参数名称。
- 缺少类型为 Power into class Powers 的字段。
我猜你可能想做什么,但你的问题需要适度。
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{
}
}
对于一组 Power
个对象,使用 Set < Power >
如果要跟踪一组 Power
个对象,请使用 Set
class。不需要可变参数,只需传递一个 Set
对象。
为了简单起见,让我们使用 Java 16 中的 Record
功能。编译器隐式创建构造函数、getter、equals
和 hashCode
,和 toString
。当 class 的主要目的是透明且不变地携带数据时,记录是合适的。使用记录使这个示例代码更短。
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]]]
如果您要定义常规 classes 而不是 record
,您将在 GameCharacter
class 上定义两个成员字段: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 + ']';
}
}
可变参数
现在我们可以回到您的具体问题:如何在构造函数中处理可变参数。
这里我们向上面看到的 class 添加第二个构造函数。第二个采用 Power
.
类型的可变参数
可变参数作为 Power
个对象的数组到达。我们可以使用 for-each 语法循环该数组的元素。我们将每个元素添加到我们选择的新 Set
实现中,在本例中为 HashSet
class.
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
class 以放弃对 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
的整个 class 的源代码,现在提供两个构造函数。
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.
}
我正在尝试创建一个名为 GameCharacter 的 class,它代表一个游戏角色并且具有 以下属性: • 名称(字符串) • 权力(一组权力对象)
如何在 class 中设置这样的对象?构造函数必须使用可变参数,因为 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;
}
}
你的代码有很多难点:
- 错误的
foreach
声明。 - 不同的类型和方法参数名称。
- 缺少类型为 Power into class Powers 的字段。
我猜你可能想做什么,但你的问题需要适度。
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{
}
}
对于一组 Power
个对象,使用 Set < Power >
如果要跟踪一组 Power
个对象,请使用 Set
class。不需要可变参数,只需传递一个 Set
对象。
为了简单起见,让我们使用 Java 16 中的 Record
功能。编译器隐式创建构造函数、getter、equals
和 hashCode
,和 toString
。当 class 的主要目的是透明且不变地携带数据时,记录是合适的。使用记录使这个示例代码更短。
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]]]
如果您要定义常规 classes 而不是 record
,您将在 GameCharacter
class 上定义两个成员字段: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 + ']';
}
}
可变参数
现在我们可以回到您的具体问题:如何在构造函数中处理可变参数。
这里我们向上面看到的 class 添加第二个构造函数。第二个采用 Power
.
可变参数作为 Power
个对象的数组到达。我们可以使用 for-each 语法循环该数组的元素。我们将每个元素添加到我们选择的新 Set
实现中,在本例中为 HashSet
class.
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
class 以放弃对 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
的整个 class 的源代码,现在提供两个构造函数。
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.
}