Просмотр полной версии : Преобразование типов на уровне класса
Можно ли сделать объект (после его создания) экземпляром другого класса (для того, чтобы унаследовать его свойства)? Если да, то как это сделать? Если нет, есть ли какой-то другой способ?
Другими словами - преобразование типов на уровне класса.
Заранее спасибо за ответ!
если я правильно понял, то вам, наверное, вот это надо Делегирование (http://ru.wikipedia.org/wiki/%D0%94%D0%B5%D0%BB%D0%B5%D0%B3%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0% B2%D0%B0%D0%BD%D0%B8%D0%B5)) 2 пункт смотрите.
Объясняю подробней.
package classes
{
public class myClass extends MovieClip
{
public var test:String = "Hello!";
}
}
import classes.*;
var A = new MovieClip();
A.height = 100;
var B = new myClass();
A = B;
result_tf.appendText(A.test + "\n");
result_tf.appendText(A.height + "\n");
Как видно из кода, объект A типа MovieClip присваивается объекту B типа myClass. Хотелось получить доступ как к стандартным свойствам MovieClip (тобишь x, y, height, width и т.д.), так и к собственноручно написанным (в данном случае test). Вместо этого, после присвоения A = B, объект A "забывает / теряет" свои родные свойства MovieClip и видит только test. На экране видно Hello! и 0 вместо Hello! и 100.
Делается это для того, чтобы добавить в объект свои свойства и методы.
После присваивания A = B; A - уже ДРУГОЙ мувик и у него может быть другая высота. Ваш кэп.
Johny_86
21.02.2012, 19:25
У тебя А и В (кстати, почему без типа) на самом деле не объекты, а ссылки на объекты в памяти. Есть объект мувик, которому ты присвоил высоту 100. на него ссылается переменная А. Есть объект типа myClass, который ты просто создал. Ему никакую высоту ты не ставил и у него она равна 0. Потом ты берешь и говоришь, что теперь ссылка А равна ссылке В - и они оба ссылаются на объект типа myClass. А у первого объекта, как была высота 100, так она и есть! Просто к нему теперь нет доступа.
Deimos747
21.02.2012, 19:26
Halfist, а что вам мешает сделать так?
import classes.*;
var A: myClass = new myClass();
A.height = 100;
result_tf.appendText(A.test + "\n");
result_tf.appendText(A.height + "\n");
import classes.*;
var A = new MovieClip();
A.height = 100;
var B = new myClass();
B.height = 999;
A = B;
result_tf.appendText(A.test + "\n");
result_tf.appendText(A.height + "\n");
Если бы свойство height (со своим значением) унаследовалось, а не заменилось, в текстовое поле вывелось бы 999. На самом же деле - 0.
Если бы свойство height (со своим значением) унаследовалось, а не заменилось, в текстовое поле вывелось бы 999. На самом же деле - 0.
откуда вы такое взяли?
Если клип пуст, то ему нельзя выставить height. Это скорее метод, чем св-во.
var A = new MovieClip();
A.height = 100;
result_tf.appendText(A.height + "\n");//0, лол
Всё дело в том, что у меня есть "фабрика", которая создаёт объекты (которые по-умолчанию, естественно, extends MovieClip, не могу же я в фабрике приказать объектам extends myClass). Вот к этим объектам потом вручную нужно "допилить" свойства, собственноручно написанные в классе myClass.
Johny_86
21.02.2012, 19:39
var a:MovieClip = new MovieClip();
a.height = 100;
var b:MyClass = new MyClass();
b.height = 999;
a = b;
trace(a.height) выведет 999!
Вы, видимо, хотите руками перестроить цепочку прототипов, как в яваскпипте. Увы, в AS3 такое не катит. Используйте паттерн Decorator.
carrotoff
21.02.2012, 21:12
Всё дело в том, что у меня есть "фабрика", которая создаёт объекты (которые по-умолчанию, естественно, extends MovieClip, не могу же я в фабрике приказать объектам extends myClass). Вот к этим объектам потом вручную нужно "допилить" свойства, собственноручно написанные в классе myClass.
Что-то слишком на кашу похоже. Почему "естественно, extends MovieClip, не могу же я в фабрике приказать объектам extends myClass" ?
Может, вы подробней распишите задачу?
Обычно за наращивание функционала отвечает Декоратор (http://ru.wikipedia.org/wiki/%D0%94%D0%B5%D0%BA%D0%BE%D1%80%D0%B0%D1%82%D0%BE%D1%80_(%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0 %B2%D0%B0%D0%BD%D0%B8%D1%8F))(как уже было замечено выше) или фасад (http://ru.wikipedia.org/wiki/%D0%A4%D0%B0%D1%81%D0%B0%D0%B4_(%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1 %8F)).
Есть, значит, у меня в библиотеке >200 фрагментов ролика, каждый из которых экспортирован для ActionScript. Класс, обрабатывающий каждый из них, я не редактировал, поскольку тогда пришлось бы создавать >200 *.as файлов. Через JSON в виде строки приходит имя класса, экземпляр которого нужно создать.
Есть следующий класс-абстракция, который наследует MovieClip:
package classes
{
import flash.display.MovieClip;
import flash.display.DisplayObject;
import flash.utils.getDefinitionByName;
public class item extends MovieClip
{
public var classInner:DisplayObject;
public var f1:String;
/* фабрика */
public function factory(strClassName:String):void
{
var className:Class = getDefinitionByName(strClassName) as Class;
this.classInner = new className();
}
}
}
А также более конкретный класс, который наследует item:
package classes
{
public class bodyClass extends item
{
public var f2:String;
public var f3:String;
public var f4:String;
}
}
В коде внутри *.fla файла происходит следующее:
var bodyLayer:Sprite = new Sprite(); addChild(bodyLayer);
var myRequest:URLRequest = new URLRequest("...");
var myLoader = new URLLoader();
myLoader.addEventListener(Event.COMPLETE, onload);
myLoader.load(myRequest);
var bodyNum:int = 0;
function onload(evt:Event):void
{
var myData:Object = JSON.decode(myLoader.data);
var key:Object;
for (key in myData.bodies)
{
var body = new bodyClass();
body.factory(myData.bodies[key].className);
var bodies:Array = [];
bodies[myData.bodies[key].className] = [];
bodies[myData.bodies[key].className][bodyNum] = body;
bodies[myData.bodies[key].className][bodyNum].classInner.f1 = "str1";
bodies[myData.bodies[key].className][bodyNum].classInner.f2 = "str2";
bodies[myData.bodies[key].className][bodyNum].classInner.f3 = "str3";
bodies[myData.bodies[key].className][bodyNum].classInner.f4 = "str4";
bodies[myData.bodies[key].className][bodyNum].classInner.height = 100;
bodies[myData.bodies[key].className][bodyNum].classInner.width = 100;
bodies[myData.bodies[key].className][bodyNum].classInner.addEventListener(MouseEvent.MOUSE_OVER,bodyOnMouseOver);
bodyLayer.addChildAt(bodies[myData.bodies[key].className][bodyNum].classInner, 0);
bodyNum++;
}
}
Мне нужно, чтобы у bodies[myData.bodies[key].className][bodyNum].classInner (объект, который является свойством класса item) были все свойства MovieClip, item и bodyClass. На самом же деле, у него есть только свойства и методы MovieClip, поскольку "В библиотеке >200 фрагментов ролика, каждый из которых экспортирован для ActionScript. Класс, обрабатывающий каждый из них, я не редактировал, а он extends MovieClip".
Слишком хитро, сами себя обманете. Зачем такое было городить вообще?
Можно выделить эти >200 фрагментов в библиотеке и поставить им базовым классом bodyClass, по-моему один и тот же куче клипов там можно поставить (тогда таки будут все св-ва).
У вас будет дублирование - bodies[myData.bodies[key].className][bodyNum] имеет поля f1, f2, f3, f4 и сам он является зачем-то мувиком и вы хотите, чтоб bodies[myData.bodies[key].className][bodyNum].classInner тоже имел эти поля (и bodies[myData.bodies[key].className][bodyNum].classInner.classInner).
Что-то надо убрать.
По-моему лучше всего, чтоб item не расширял MovieClip и чтоб не надо было classInner быть наследником bodyClass =) Данные брать из bodies[myData.bodies[key].className][bodyNum] (который bodyClass).
Или bodies[myData.bodies[key].className][bodyNum] - должен быть классом, которому таки поставлен bodyClass базовым классом, который создаст поправленная (чтоб она такое могла делать) фабрика.
И массив bodies - используется не стандартно и запутывает тем, что он массив, он у вас как Object используется.
Ещё загадочен массив bodies[myData.bodies[key].className] - в нём всегда один элемент будет?
PS: внутри .fla кода не должно быть, особенно если он по сложности как тот, что выше, используйте document class.
Можно выделить эти >200 фрагментов в библиотеке и поставить им базовым классом bodyClass, по-моему один и тот же куче клипов там можно поставить (тогда таки будут все св-ва).
Нельзя, поскольку из JSON может прийти одно из >200 имён классов, экземпляр которого нужно создать (каждый внешне выглядит по-разному).
-De-, снимаю шляпу, у меня на всей этой перелинковке мозг сломался :)
Массив нужен для того, чтобы "всунуть" туда несколько объектов, т.к. из JSON приходит не одна запись, а также знать, к какому конкретно объекту в данный момент идёт обращение. Они разные, поскольку на каждой итерации цикла bodyNum++.
У меня давно сдох CS4, потому плохо помню и проверить не могу, может и нельзя )
Но символу можно поставить класс (который один из >200 имён и я так понял они все тупо мувиклипы). И можно поставить базовый класс. Который у всех этих > 200 имён будет один bodyClass.
PS: у вас не будет в массиве bodies[myData.bodies[key].className] более одного элемента т.к. он каждый раз создаст новый массив на месте предыдущего. Наверное это баг и
вместо
bodies[myData.bodies[key].className] = [];
надо
if(null == bodies[myData.bodies[key].className])
bodies[myData.bodies[key].className] = [];
И может там стоит в этот массив тупо push делать, а не тянуть bodyNum?
Класс для каждого фрагмента ролика указан (их >200).
А вот базовый класс нельзя изменить, поскольку "Указанный базовый класс является собственным классом и будет определён в проигрывателе во время выполнения. Он не может быть изменён.". Его значение, конечно же, flash.display.MovieClip.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.