PDA

Просмотр полной версии : Возможно ли динамически наследовать классы


Isfet
16.09.2013, 13:02
Допустим есть Json- объект, при его парсении вытаскиваю свойства рисуемых объектов, допустим свойство type, если type = 1, то наследовать DrawObject от Shape, если 2 , то от Sprite. Можно ли такое сделать?

Babylon
16.09.2013, 13:46
Нет конечно, но ты можешь сделать фабрику инстансов классов, имплементирующих предопределенный интерфейс IDrawObject

MikroAcse
16.09.2013, 22:06
Только в haxe и только при компиляции.

expl
16.09.2013, 22:37
по моему при компиляции - это не динамически :)

Допустим есть Json- объект, при его парсении вытаскиваю свойства рисуемых объектов, допустим свойство type, если type = 1, то наследовать DrawObject от Shape, если 2 , то от Sprite. Можно ли такое сделать?

Что-то подсказывает, что не нужно здесь фокусов с наследованием, а надо просто взять и решить задачу.

public class Parser
{
private static function parseCommon(object:DisplayObject, json:Object):void {
object.x = json["x"];
object.y = json["y"];
...
}
private static function parseSpritePart(sprite:Sprite, json:Object):void {
for each (var i:Sprite in json["childs"]) {
sprite.addChild(NewDisplayObject(i));
}
}
public static function newDisplayObject(json:Object):DisplayObject {
if (json["type"] == "Sprite") {
var sprite:Sprite = new Sprite();
ParseCommon(sprite, json);
ParseSpritePart(sprite, json);
return sprite;
}
if (json["type"] == "Shape") {
var shape:Shape = new Shape();
ParseCommon(shape, json);
return shape;
}
return null;
}
}
...
DisplayObject object = Parser.newDisplayObject(JSON.parse(text));

in4core
17.09.2013, 01:18
expl последняя строчка) на какой язык перешел?

expl
17.09.2013, 11:43
на хороший
*var object:DisplayObject = Parser.newDisplayObject(JSON.parse(text));

Isfet
17.09.2013, 13:46
Что-то подсказывает, что не нужно здесь фокусов с наследованием, а надо просто взять и решить задачу.

Да, фабричный метод хорош, но в том то и дело, что кроме основного функционала классов Sprite и Shape, он должен еще содержать функционал класса DrawObject.

Чтобы не делать 2 класса DrawObjectShape и DrawObjectSprite , в которых будет одинаковый код

expl
17.09.2013, 22:13
Да, фабричный метод хорош, но в том то и дело, что кроме основного функционала классов Sprite и Shape, он должен еще содержать функционал класса DrawObject.
Ну и отлично, добавляем метод:

private static function parseDrawableObject(Graphics g, json:Object):void {
g.lineStyle(0, json["color"]);
g.drawCircle(json["circle_x"], json["circle_y"], json["radius"]);
}

И добавляем 2 строчки в основную функцию:

public static function newDisplayObject(json:Object):DisplayObject {
if (json["type"] == "Sprite") {
var sprite:Sprite = new Sprite();
ParseCommon(sprite, json);
ParseSpritePart(sprite, json);
ParseDrawableObject(sprite.graphcis, json);// раз
return sprite;
}
if (json["type"] == "Shape") {
var shape:Shape = new Shape();
ParseCommon(shape, json);
ParseDrawableObject(sprite.graphcis, json);// два
return shape;
}
if (json["type"] == "TextField") {
var tf:TextField = new TextField();
ParseCommon(tf, json);
...
// А сюда не добавляем
return tf;
}
return null;
}

Чтобы не делать 2 класса DrawObjectShape и DrawObjectSprite , в которых будет одинаковый код
А где мы здесь вообще делаем новые классы? :)

Да, фабричный метод хорош
Это не фабричный метод, это тупая декомпозиция на функции. Часто тупое решение - оно самое верное.
Паттерном "фабричный метод" называют несколько другое:
http://ru.wikipedia.org/wiki/%D0%A4%D0%B0%D0%B1%D1%80%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_(%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D 0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F)

Хотя здесь можно назвать Parser статической фабрикой, а newDisplayObject - методом статичной фабрики (просто названия совпадают паттерна и метода, хотя здесь ситуация совсем не похожа на фабричный метод - у нас тут никакие методы не перегружаются в подклассах, у нас тут вообще один класс и тот статичный, его, конечно, при необходимости, можно сделать нестатичным, тут не принципиально)

P.S. Если вас напрягает добавление этих -2х строчек, у вас куча объектов со своими особенностями парсинга/перевода обратно в JSON и вы хотите более гибко добавлять эти объекты - могу подсказать как этого добиться с наследованием и прочими извращениями. Но если у вас 5 - 10 типов объектов, и добавление новых - редкость - решение с простыми функциями - самое лучшее.

Wolsh
18.09.2013, 00:00
В любом случае Вы не можете наследоваться от нескольких/разных классов.
Можно заморочиться и заменить наследование композицией, но по-моему проще продублировать код, особенно если для Вас критична разница (по весу?) между Спрайтом и Шейпом (то какой-то еще экземпляр на борту это уж тем более перебор).