提问人:tmsnvk 提问时间:10/25/2023 最后编辑:Federico klez Cullocatmsnvk 更新时间:10/25/2023 访问量:94
当我需要更改对象的类型时,有没有一种优雅的方法来重新创建对象?
Is there an elegant way to recreate an object when I need to change its type?
问:
我的一个练习任务是让战士参与任务,以及一个可以计算/过滤/跟踪战士和任务的聚合器类。
我有一个 Fighter 抽象类和三种不同类型的 Fighter(Junior、Medior 和 Senior),它们继承了这个具有许多字段的抽象类。
该方案应该能够将战士提升到更高的军衔——从初级晋升为中级,从中级晋升为高级。我知道在初始化后无法更改对象的类型,但是有没有比我当前的解决方案更好/更优雅的解决方案?即我创建一个更高级别的战斗机的新对象,将原始对象的数据复制到其中,然后删除原始对象。
答:
1赞
Basil Bourque
10/25/2023
#1
正如所评论的,听起来排名应该只是你班级的一个属性。Fighter
除非子类具有超出超类的其他数据或行为,否则不应使用继承。
下面是一个完整的示例类。我们定义为具有三个命名常量对象的枚举,即您的三个等级。我们有一个 getter 和一个 setter 方法,供您更改实例上的排名字段。Rank
package work.basil.example;
import java.util.Objects;
public final class Fighter
{
// Member fields
private String name;
private Rank rank;
enum Rank { JUNIOR, MEDIOR, SENIOR; }
// Constructor
public Fighter ( String name ,
Rank rank )
{
this.name = name;
this.rank = rank;
}
// Accessors
public String getName ( )
{
return name;
}
public void setName ( final String name )
{
this.name = name ;
}
public Rank getRank ( )
{
return rank;
}
public void setRank ( final Rank rank )
{
this.rank = rank;
}
// `Object` overrides.
@Override
public boolean equals ( Object obj )
{
if ( obj == this ) return true;
if ( obj == null || obj.getClass ( ) != this.getClass ( ) ) return false;
var that = ( Fighter ) obj;
return Objects.equals ( this.name , that.name ) &&
Objects.equals ( this.rank , that.rank );
}
@Override
public int hashCode ( )
{
return Objects.hash ( name , rank );
}
@Override
public String toString ( )
{
return "Fighter[" +
"name=" + name + ", " +
"rank=" + rank + ']';
}
}
用法:
Fighter alice = new Fighter ( "Alice" , Fighter.Rank.MEDIOR ) ;
alice.setRank( Rank.SENIOR ) ; // Alice earned a promotion.
评论
1赞
Bohemian
10/25/2023
...他们可以被降级。
0赞
tmsnvk
10/25/2023
嗨,罗勒,谢谢,这是合理的,我想了想。我忘了说,这三种类型的战士可以执行不同的任务,例如初级只能执行任务 A,调解员 A 和 B,高级战士 A、B、C。MissionTypes 存储在枚举中。目前,这些类型存储在每个战斗机类的静态变量中。如果我按照您的示例进行操作,则必须存储一个列表并在构造函数中设置 MissionTypes。这听起来似乎很合理,但是,我被警告不要在构造函数中使用过多的逻辑。您对此有何看法?干杯,T
0赞
Basil Bourque
10/30/2023
@tmsnvk构造函数确实应该保持简单。但是,如果输入的数据验证可以保持简单(如果不简单,请使用构建器),则对于构造函数来说是合法的函数。验证分配的任务时,请使用详尽的 switch
语句,每个级别都有一个大小写。如果该等级的任务是错误的,则抛出非法参数异常。提示:您可以使用来保留一组适合每个等级的任务;叫。EnumSet
Set#contains
0赞
tmsnvk
10/31/2023
感谢@BasilBourque的详细解释,非常感谢!
下一个:Java 在对象内创建对象
评论
rank