2013-10-15 3 views
0

У меня есть объект отображения, который имеет кучу свойств. Я хочу сделать клонирование этого класса. Я понимаю, что невозможно сделать глубокую копию пользовательского класса в AS3, поэтому я прибегнул к простому копированию свойств, а затем через метод clone создайте новый экземпляр с теми же точными свойствами, что и оригинал.Копирование/клонирование свойств экземпляра?

У меня возникли проблемы с получением всех свойств объекта display. Конечно, я могу просто позвонить каждый уаг один за другим и положить его в массив и возвращает этот массив в клоне, как это:

function clone():Array 
    array.push(displayObject.x); 
    array.push(displayObject.y); 
    array.push(displayObject.price); 
    return array; 

Но это на самом деле не объектно-ориентированного. Поэтому я ищу способ получить все свойства объекта, которые затем поместят эти свойства в новый объект.

О, и я бегу на AS3 для Air not Flex, поэтому я не могу использовать mx.utils.ObjectUtil, что является способом сделать это.

+0

вы можете использовать 'flash.utils.describeType '? – Cherniv

+0

К сожалению, он не читает приватную собственность. – Banzboy

+0

Невозможно получить доступ к закрытым и защищенным свойствам –

ответ

1

Вы не можете копировать приватную собственность. Вы можете использовать ByteArray скопировать свойства

Собака является целевым классом клона

public class Dog { 

    public function Dog() 
    { 
    } 

    public function setName($name:String):void { 
     name = $name; 
    } 

    public var subDogs:Array = []; 

    public var age:int; 

    private var name:String; 
} 

А вот как клонировать

var dog:Dog = new Dog(); 
dog.subDogs.push(new Dog()); 
dog.setName("puppy"); 
dog.age = 15; 

registerClassAlias("vo.Dog", vo.Dog); 
var dogA:Object = CloneUtil.copy(dog); 

var d:Dog = copy(dog) as Dog; 

private function copy(source:Object):* { 

     var ba:ByteArray = new ByteArray(); 
     ba.writeObject(source); 

     ba.position = 0; 

     return ba.readObject(); 
} 
+0

+1, но вам нужно будет зарегистрироватьClassAlias ​​каждый пользовательский тип и вектор recusivly (возможно, здесь не проблема) –

+0

В моем случае registerClassAlias, используемый только в сериализации словаря, содержит файлы cfg в файл game.data и десериализовать файл данных на объект словаря. Поэтому я думаю, что это приемлемо. – Pan

0
package 
{ 
    import flash.display.Sprite; 
    import flash.utils.Dictionary; 
    import flash.utils.describeType; 
    import flash.utils.getQualifiedClassName; 

    public class DynamicClone extends Sprite 
    { 
     public function DynamicClone() 
     { 
      var p1 : Player = new Player; 
      p1.name = "Simsoft"; 
      p1.hiddenAccessor = 10; 

      var p2 : * = clone(p1); 

      // p2 is a Player instance 
      trace(getQualifiedClassName(p2)); // Player 

      // p1 and p2 are not the same instance 
      trace(p1 == p2); // False 

      // But public properties are cloned 
      trace(p2.name); // Simsoft 
      trace(p2.hiddenAccessor); // 10 
     } 

     public function clone(source : Object, cloneGetSet : Boolean = true) : * 
     { 
      if(!source) 
       return null; 

      if(source is Array || source is Vector.<*> || source is Vector.<uint> || source is Vector.<int> || source is Vector.<Number> || source is Vector.<Boolean>) 
       return source.concat(); 

      var newInstance : Object = new (source.constructor); 

      // Copy dynamic var 
      for(var dynamicVar : String in source) 
       newInstance[ dynamicVar ] = source[ dynamicVar ]; 

      var typeDescription : XML = describeType(source); 

      // Copy variables 
      for each(var variable : String in [email protected]) 
       newInstance[ variable ] = source[ variable ]; 

      // Copy getter/setter 
      if(cloneGetSet) 
       for each(var getset : String in typeDescription..accessor.(@access == "readwrite")[email protected]) 
        newInstance[ getset ] = source[ getset ]; 

      return newInstance; 
     } 
    } 
} 

internal class Player { 

    // Will be clone 
    public var name : String; 

    // Won't be clone 
    private var _score : uint; 

    // Will be clone throught getter/setter 
    private var _hidden : uint; 

    // Can be clone because we have a getter and a setter 
    public function get hiddenAccessor():uint 
    { 
     return _hidden; 
    } 

    public function set hiddenAccessor(value:uint):void 
    { 
     _hidden = value; 
    } 
} 
Смежные вопросы