最近,我在C++上开发了一个游戏,在这个游戏中,我实现了命令模式来管理键盘输入来控制宇宙飞船。在实例化所有命令时,我会将宇宙飞船指针传递给每个构造函数,以便所有命令都使用相同的宇宙飞船对象。
这种模式在C++中很有意义,因为您可以通过引用传递,但在Java语言中一切都是通过值传递的。如果我试图在Java中实现同样的事情,我如何让每个命令指向相同的对象?
在我所见过的Java中使用的Command模式的所有示例中,每个Command的成员变量是副本还是引用都没有区别。
发布于 2012-02-15 19:11:59
Java在所有情况下都是通过值传递的,但是所有的“非原始”类型都是以引用的形式存在的,所以对于String、List或Spaceship这样的类型,你实际上是在传递一个引用--通过值传递是因为你是通过值传递引用的。这是一种相当混乱的表达方式,我总觉得。
无论如何,它的结果是如果您有一个(大大简化的) Command类
public class Command {
private Spaceship spaceship;
public Command(Spaceship ship) {
spaceship = ship;
}
}然后你这样做:
Spaceship ship = new Spaceship();
List<Command> ships = new List<Command>();
for (int i = 0; i < 40; i++) {
ships.add(new Command(ship));
}然后,这些Command对象中的每个对象都有一个对同一Spaceship对象的引用。通过值传递引用不会导致引用所指向的Spaceship对象的副本。但是,如果您传递的是ints,那么您确实是在传递副本。
只要记住像int这样的原始类型和像String这样的对象类型之间的区别就可以了。记住,基本类型名称以小写字母开头(并且永远不能由用户定义),而对象类型以大写字母开头,这一点很有帮助。所有用户定义的类型都是对象类型。
发布于 2012-02-15 19:04:05
在java中,他们通过“值”来传递...您传递的是将实现execute方法的真实对象。不同对象之间的共享引用可以通过适当的面向对象设计或公共属性的查找方法注入来实现。命令模式示例取自wikipedia
/*the Command interface*/
public interface Command {
void execute();
}
/*the Invoker class*/
import java.util.List;
import java.util.ArrayList;
public class Switch {
private List<Command> history = new ArrayList<Command>();
public Switch() {
}
public void storeAndExecute(Command cmd) {
this.history.add(cmd); // optional
cmd.execute();
}
}
/*the Receiver class*/
public class Light {
public Light() {
}
public void turnOn() {
System.out.println("The light is on");
}
public void turnOff() {
System.out.println("The light is off");
}
}
/*the Command for turning on the light - ConcreteCommand #1*/
public class FlipUpCommand implements Command {
private Light theLight;
public FlipUpCommand(Light light) {
this.theLight = light;
}
public void execute(){
theLight.turnOn();
}
}
}发布于 2012-02-15 19:09:54
因为Java总是通过值传递,所以你需要做一些可变的事情来传递(传递一个可变对象)。
考虑这个例子:
在这种支持按引用传递的不可知语言中
string commandArg = "";
new StringCommand().execute(commandArg);
Console.write(commandArg);在StringCommand.execute(string arg)中,您有arg += "Hello World",那么您的输出将是Hello World。
在Java中,只需传递一个StringBuilder,如下所示:
StringBuilder sb = new StringBuilder();
new StringCommand().execute(sb);
System.out.println(sb.toString());其中,StringCommand.execute(StringBuilder sb)包含:
sb.append("Hello World");在StringCommand.execute中通过值传递StringBuilder引用。简而言之,基元类型是通过值传递的,对于对象,对象的引用是通过值传递的。
我希望这能帮到你。
https://stackoverflow.com/questions/9292079
复制相似问题