【问题标题】:Java - class objects used instead of prototyping?Java - 使用类对象而不是原型设计?
【发布时间】:2013-10-18 15:04:58
【问题描述】:

我读到您可以使用类对象而不是使用原型进行克隆。但是我不明白使用类对象代替它意味着什么?如果有人理解使用类对象而不是原型模式意味着什么,谁能举个例子?..

【问题讨论】:

  • 我们在这里讨论的是 Java 还是 JavaScript?
  • 问题不清楚。请澄清。
  • 您阅读的文章有链接吗?原型设计是创建对象层次结构时的一种解决方案,相关操作要么昂贵要么不可行。以游戏状态为例 - 假设您玩了 2 个小时并保存了状态。当您恢复时,克隆先前保存的状态比运行所有价值 2 小时的操作更容易。因此,参考您阅读的内容可能会帮助您获得更好的答案。

标签: java class object prototype clone


【解决方案1】:

从 Java 5 开始,java.lang.Class 在其自身类型上是通用的。这允许类以类型安全的方式创建其实例。

当您使用带有克隆的原型时,您可以执行以下操作:

interface Calculator {
    void setA(int a);
    void setB(int b);
    int compute();
    Calculator copy();
}
class Adder implements Calculator {
    private int a,b;
    public void setA(int a) {this.a=a;}
    public void setB(int b) {this.b=b;}
    public int compute() {return a+b;}
    public Calculator copy() {
        Adder res = new Adder();
        res.a = a;
        res.b = b;
        return res;
    }
}
class Multiplier implements Calculator {
    private int a,b;
    public void setA(int a) {this.a=a;}
    public void setB(int b) {this.b=b;}
    public int compute() {return a*b;}
    public Calculator copy() {
        Multiplier res = new Multiplier();
        res.a = a;
        res.b = b;
        return res;
    }
}
class Test {
    static void computeWithPrototype(Calculator proto) {
         Calculator calc = proto.copy();
         calc.setA(123);
         calc.setB(321);
         System.out.println(calc.compute());
    }
    public static void main(String[] args) throws Exception {
        computeWithPrototype(new Adder());
        computeWithPrototype(new Multiplier());
    }
}

Demo of the above approach on ideone.

您可以使用Class<T> 而不是copy 方法重写它,如下所示:

interface Calculator {
    void setA(int a);
    void setB(int b);
    int compute();
}
class Adder implements Calculator {
    private int a,b;
    public void setA(int a) {this.a=a;}
    public void setB(int b) {this.b=b;}
    public int compute() {return a+b;}
}
class Multiplier implements Calculator {
    private int a,b;
    public void setA(int a) {this.a=a;}
    public void setB(int b) {this.b=b;}
    public int compute() {return a*b;}
}
class Test {
    static <T extends Calculator> void computeWithClass(Class<T> calcClass)
    throws Exception {
         Calculator calc = calcClass.newInstance();
         calc.setA(123);
         calc.setB(321);
         System.out.println(calc.compute());
    }
    public static void main(String[] args) throws Exception {
        computeWithClass(Adder.class);
        computeWithClass(Multiplier.class);
    }
}

Demo of the second approach on ideone.

【讨论】:

    【解决方案2】:

    在java中,当你创建一个对象时,它有一个引用内存。因此,当您尝试将该对象分配给变量时,您会传递参考内存。

    例子:

    Person a = new Person(); a.setName("Person abc");
    Person b = a; b.setName("Person yzw"); 
    System.out.print(a.getName());
    System.out.print(b.getName());
    

    因此,当您修改属于此内存引用的属性时,您会同时修改两者。 它将打印:“yzw yzw”;

    因此,如果您不希望它发生,请使用 Cloneable 接口:

    public class Person implements Cloneable{
    
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    

    因此,当您调用 clone() 方法时,您将拥有两个不同的对象。 示例:

    Person a = new Person();
    a.setName("Person abc");
    Person b = (Person)a.clone(); 
    System.out.print(a.getName());
    System.out.print(b.getName());
    

    它将打印:“abc yzw”;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-27
      • 1970-01-01
      • 2012-07-02
      • 2016-03-30
      • 2019-01-09
      • 1970-01-01
      • 2011-03-06
      相关资源
      最近更新 更多