Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   наследование классов: реализация функции clone() объектов (http://www.flasher.ru/forum/showthread.php?t=140482)

litebox 31.05.2010 13:18

наследование классов: реализация функции clone() объектов
 
Всем доброго времени суток.
Есть такая иерархия классов:
BaseObject - содержит базовые свойства, присущие всем объектам игрового мира
WorldObject - наследник класса BaseObject, основная графическая единица игры

У обоих этих объектов есть метод clone(), который создает и возвращает копию этого объекта.
Вопрос в том, как правильно реализовать эту функцию в классе WorldObject, чтобы:
свойства, присущие классу BaseObject копировались в его функции clone(), а свойства, присущие классу WorldObject, копировались в его функции clone()?

Самое лучшее, что придумалось, выглядит так:
Код AS3:

public class BaseObject
{
        private var identifier:String;
        private var objectType:uint;
        private var objectName:String;
 
        public function clone(baseObjectPtr:BaseObject = null):BaseObject
        {
                baseObjectPtr.id = id;
                baseObjectPtr.name = name;
                baseObjectPtr.type = type;
 
                return null;
        }
 
        public function get id():String
        {
                return identifier;
        }
 
        public function set id(value:String):void
        {
                identifier = value;
        }
 
        public function get name():String
        {
                return objectName;
        }
 
        public function set name(value:String):void
        {
                objectName = value;
        }
 
        public function get type():uint
        {
                return objectType;
        }
 
        public function set type(value:uint):void
        {
                objectType = value;
        }
}

Код AS3:

public class WorldObject extends BaseObject
{
        private var currAnim:String;
 
        override public function clone(baseObjectPtr:BaseObject = null):BaseObject
        {
                var dublicate:WorldObject = new WorldObject();
 
                super.clone(dublicate);
 
                dublicate.currAnim = currAnim;
 
                return dublicate;
        }
}

т.е. BaseObject сам по себе не используется и "в чистом виде" не клонируется, а клонируется только из классов-наследников. Такая реализация меня не очень радует, хочется узнать Ваше мнение, как это можно организовать покрасивее.

i.o. 31.05.2010 13:46

Есть такой вариант:
Код AS3:

public class BaseObject
{
...............
 
        public function clone():BaseObject
        {
                var _clone:BaseObject = new BaseObject();
 
                _clone._copyFrom_BaseObject( this );
 
                return _clone;
        }
 
        protected function _copyFrom_BaseObject( source:BaseObject ):void
        {
                this.id = source.id;
                this.name = source.name;
                this.type = source.type;
        }
 
...............
 
}

Код AS3:

public class WorldObject extends BaseObject
{
        private var currAnim:String;
 
        override public function clone():BaseObject
        {
                return cloneAsWorldObject();
        }
 
        public function cloneAsWorldObject():WorldObject
        {
                var _clone:WorldObject = new WorldObject();
 
                _clone._copyFrom_WorldObject( this );
 
                return _clone;
        }
 
        protected function _copyFrom_WorldObject( source:WorldObject ):void
        {
                this._copyFrom_BaseObject( source );
 
                this.currAnim = source.currAnim;
        }
}


i.o. 31.05.2010 13:49

Ну как, подходит?

litebox 31.05.2010 14:43

да как то тоже не очень по ООП-шному ). Луче уж тогда просто описывать все поля в самом классе WorldObject (и его собственные и из базового класса), просто не вызывая super.clone() вообще

incvizitor 31.05.2010 19:35

Код AS3:

public function clone(baseObjectPtr:BaseObject = null):BaseObject {
        baseObjectPtr.id = id;
        baseObjectPtr.name = name;
        baseObjectPtr.type = type;
 
        return baseObjectPtr;
}

Код AS3:

override public function clone(baseObjectPtr:BaseObject = null):BaseObject {
        var dublicate:WorldObject = super.clone(new WorldObject()) as WorldObject;
        dublicate.currAnim = currAnim;
        return duplicate;
}

Добавлено через 2 минуты
Это что бы работало, а вообще baseObjectPtr можно было бы создавать в самой функции clone, а не параметром передавать.

wvxvw 31.05.2010 20:07

Как раз тот случай когда пригодились бы виртуальные методы. Вообще, я думаю, что параметр функции клонирования ни к чему, проще жить будет если она сама все что ей нужно будет создавать.

i.o. 31.05.2010 20:26

incvizitor, неувязочка небольшая получилась: в BaseObject клонируется исключительно в переданный объект (и нового не создается), а в WorldObject переданная ссылка нигде и не используется. Логика то метода разная получается - нехорошо ))

incvizitor 31.05.2010 21:04

i.o., прочитайте комментарий который я оставил после своего поста, я там уже ответил на Вашу претензию =)

Добавлено через 3 минуты
А вообще, думаю писать надо вот так:

Код AS3:

public function clone():BaseObject {
        var curClass:Class=getDefinitionByName(getQualifiedClassName(this));
        baseObjectPtr:curClass= new curClass();
        _initProps(baseObjectPtr);
        return baseObjectPtr;
}
 
protected function _initProps(baseObjectPtr:BaseObject):void{
}


wvxvw 31.05.2010 21:25

Только так не скомпилируется, да и проще мижно:
Код AS3:

var curClass:Class = (this as Object).constructor as Class;
return new curClass() as BaseObject;

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

-De- 31.05.2010 21:40

Цитата:

Сообщение от wvxvw (Сообщение 912089)
Как раз тот случай когда пригодились бы виртуальные методы.

Во флэше они ж, как и в яве, все виртуальные, не? Как в шарпе/яве/с++ лучше сделать-то?
PS: для веселухи метод с writeObject:

Код AS3:

public function clone():Base {
                        var b:ByteArray = new ByteArray();
                        registerClassAlias("Base", (this as Object).constructor as Class);
                        b.writeObject(this);
                        b.position = 0;
                        return b.readObject();
                }
public override function clone():Base {
                        var b:ByteArray = new ByteArray();
                        registerClassAlias("Derived", (this as Object).constructor as Class);
                        b.writeObject(this);
                        b.position = 0;
                        return b.readObject();
                }



Часовой пояс GMT +4, время: 11:59.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.