也许这会有所帮助;在运行时改变行为的一种常用方法是策略模式;这个想法是保持 Body 类中所有身体类型的共同点,并将不同的行为分成不同的策略,这样当身体改变类型时,策略就可以交换。它们可以实现一个接口,比如 BodyBehavior,而不是让 BlackHole、Planet 和 Star 扩展 Body;
public interface BodyBehaviour {
String getType ();
Double getLuminosity (Body body);
// anything else you need that's type specific....
}
public class PlanetBodyBehavior implements BodyBehaviour {
public static final String TYPE = "Planet"
@Override
public String getType() {
return TYPE;
}
@Override
public Double getLuminosity(Body body) {
// planet specific luminosity calculation - probably 0
return calculatedLuminosity;
}
}
你的身体等级看起来像这样;
public class Body {
private Double mass;
// coordinates,radius and other state variables
private BodyBehavior bodyBehaviour;
public void setBodyBehaviour (BodyBehaviour behaviour) {
this.bodyBehaviour = behaviour;
}
public String getBodyType () {
bodyBehaviour.getType();
}
public Double getLuminosity () {
bodyBehavior.getLuminosity(this);
}
}
对于你的模拟,你可以有一些类似的东西;
// init - note we keep our behaviors stateless so we only need one instance of each
public class Simulation () {
BodyBehaviour planetBehavior = new PlanetBodyBehavior();
BodyBehaviour starBehavior = new StarBodyBehavior()
BodyBehaviour blackHoleBehavior = new BlackHoleBodyBehavior()
// Just showing initialisation for a single star...
Body body = new Body(initilising params....)
body.setBehaviour (starBehavior);
// iterations....
while (!finished) {
// assume we have many bodies and loop over them
for (Body body : allBodies) {
// update body positions etc.
// check it's still a star - don't want to be changing it every iteration...
if (body.hasBecomeBlackHole() {
// and this is the point of it all....
body.setBodyBehaviour(blackHoleBehavior);
}
}
}
}
模拟愉快!
请注意,在这种情况下,调用行为更改的是顶层模拟循环,但您可以将其添加到您的 BodyBehavior;
boolean hasBecomeBlackHole (Body body);
在正文中你可以做类似的事情
public boolean hasBecomeBlackHole () {
bodyBehaviour.hasBecomeBlackHole(this);
}
对于 StarBodyBehavior;
public boolean hasBecomeBlackHole (final Body body) {
return doSomeCalculations(body.getMass(), body.getRadius());
}
对于行星和黑洞
public boolean hasBecomeBlackHole (final Body body) {
return false;
}