Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Обращение из родителя к унаследованной static переменной потомка (http://www.flasher.ru/forum/showthread.php?t=159952)

AirDecade 07.07.2011 04:29

Обращение из родителя к унаследованной static переменной потомка
 
Есть класс-родитель и несколько унаследованных от него потомков.
Код AS3:

public class parent
{
    protected static var b:Bitmap;
    //...
 
    public static function setBitmap(_b:Bitmap):void
    {
        b = _b;
    }
}

Код AS3:

public class child1 extends parent
{
    //...
    public function foo(_b:Bitmap):void
    {
        //...
      setBitmap(_b);
    }
}

Код AS3:

public class child2 extends parent
{
    //...
    public function bar(_b:Bitmap):void
    {
        //...
      setBitmap(_b);
    }
}

В ходе работы классов потомков периодически нужно заносить в переменную b каждого класса потомка битмап. Для этого я вызываю общую для них всех (а потому написанную в классе-родителе) функцию setBitmap. Но она заносит битмап в static переменную родителя, а не класса-потомка, который её вызвал. А нужно именно в static переменную класса потомка.

Понятно, что это можно решить, скопировав функцию setBitmap в каждый класс-потомок вместо класса родителя. Но это не правильно. (я привёл упрощённый пример, на практике setBitmap содержит много кода, хотелось бы менять его из одного места, а не из 20).

Понятно, что можно использовать getQualifiedClassName в паре с getDefinitionByName, чтобы в родителе всё таки записать битмап в правильный класс. Но неужели нет более простого решения?

goodguy 07.07.2011 07:12

Цитата:

неужели нет более простого решения?
Есть. Отказаться от этой protected static переменной и, сделать ее public static, если уж на то пошло.
А вообще, лично я не вижу абсолютно никакого смысла во всех этих извращениях. Может поясните, зачем это нужно на практике?
Ведь обращение к статическим полям происходит в любом случае не через экземпляр класса

kackbip 07.07.2011 07:32

Изврат полнейший. Уберите нафик static. Работайте с экземплярами.

BuKT 07.07.2011 07:43

А разве статические переменные наследуются?

goodguy 07.07.2011 08:10

Конечно нет. Но обращение к ним может происходить в классах потомках напрямую

AirDecade 07.07.2011 08:43

Цитата:

Сообщение от goodguy (Сообщение 1009453)
Есть. Отказаться от этой protected static переменной и, сделать ее public static, если уж на то пошло.

А чем это поможет? Статическая функция родителя всё равно будет писать в свою статическую переменную, а не в переменную вызвавшего эту функцию потомка. Собственно, она и была public, я неправильно написал...

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

От родителя унаследовано много разных классов. Но функции, имеющие дело с данными, которые я пытаюсь хранить в static переменных, одинаковы для всех этих классов, поэтому хочется иметь их в родителе. (Только нужно чтоб эти функции брали данные из static перменных потомка, который их вызвал, а не родителя, где находится функция).

Что можно сделать:
1)
Цитата:

Сообщение от kackbip (Сообщение 1009455)
Уберите нафик static. Работайте с экземплярами.

Тогда не будет вопросов с обращением именно к полям потомка в функции родителя. Но тогда надо будет инициализировать эти экземпляры как-то. И не один раз на старте программы, а при каждом создании экземпляра потомка. А для этого их нужно изначально где-то хранить. Таким образом, возвращаемся туда, откуда пришли - где же их хранить.

2) Извращаться с getQualifiedClassName и getDefinitionByName, чтобы понять какой именно потомок вызвал функцию и обратиться к его полям.

3) Сделать класс, который будет хранить все эти данные за потомков, потомки (или родитель - становиться не важно) просто обращаются к нему за ссылкой на данные, указывая в аргументе класс, от которого ему нужны данные. Он инкапсулирует все нюансы их инициализации, что я пытаюсь запихнуть в родителя.

Наверно, третий вариант и является "правильным".
Только в моём случае он более морочный. Больше придётся переделывать. Поэтому я выбрал второй.

Цитата:

Сообщение от BuKT (Сообщение 1009457)
А разве статические переменные наследуются?

As a matter of fact - наследуются.

Добавлено через 2 минуты
Цитата:

Сообщение от goodguy (Сообщение 1009459)
Конечно нет. Но обращение к ним может происходить в классах потомках напрямую

мм? 0_о А как тогда ещё назвать то, что они делают?
Классы потомки могут обращаться к родительским static, но у них остаются их собственные 'унаследованные' static.

goodguy 07.07.2011 09:54

Цитата:

As a matter of fact - наследуются.
As a matter of fact - не наследуются.
Особенно, советую обратить внимание на то, что выделенно жирным шрифтом: Static properties not inherited
Цитата:

А чем это поможет? Статическая функция родителя всё равно будет писать в свою статическую переменную, а не в переменную вызвавшего эту функцию потомка. Собственно, она и была public, я неправильно написал...
Очевидно, надо изобрести другой способ выполнения этой задачи.

AirDecade 07.07.2011 09:56

Я провёл тестирование наследования static переменной. Результат: при большом желании она наследуется.
Вот проект под flashDevelop с примером: http://dl.************/u/8648712/inheritanceTest.rar
И вот непосредственно код:

Код AS3:

package 
{
        import flash.display.Bitmap;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.utils.getDefinitionByName;
        import flash.utils.getQualifiedClassName;
 
        public class Main extends Sprite
        {               
                public function Main():void
                {
                        if (stage) init();
                        else addEventListener(Event.ADDED_TO_STAGE, init);
                }
 
                private function init(e:Event = null):void
                {
                        removeEventListener(Event.ADDED_TO_STAGE, init);
                        // entry point
 
                        //Инициализируем static переменные с bitmapData детей через родителя
                        Parent.initChild("Child1");
                        Parent.initChild("Child2");
 
                        //На данном этапе никто больше не меняет никакую bitmapData нигде.
                        //Однако, как видно из работающей флешки, они разные для child1 и child2
 
                        //Если бы static переменная из Parent не унаследовалась в child1 и child2
                        //То там бы хранилась либо одна bitmapData, либо другая, но
                        //как видно, bitmapData разные.
 
                        //Да, всё это изврат.
                        //Но это доказывает, что static переменная унаследовалась.
                        //Или как ещё это трактовать?
 
                        var child1:Child1 = new Child1();
                        var child2:Child2 = new Child2();
 
                        var sq:String;
                        var cl:Class;
 
                        trace(Parent.bitmapData);
 
                        sq = getQualifiedClassName(child1);
                        cl = getDefinitionByName(sq) as Class;
                        var bitmap:Bitmap = new Bitmap(cl.bitmapData);
                        trace(cl.bitmapData.height);
                        addChild(bitmap);
 
                        sq = getQualifiedClassName(child2);
                        cl = getDefinitionByName(sq) as Class;                       
                        bitmap = new Bitmap(cl.bitmapData);
                        trace(cl.bitmapData.height);
                        bitmap.x = 100;
                        addChild(bitmap);
                }               
        }       
}

Код AS3:

package 
{
        import flash.display.Bitmap;
        import flash.display.BitmapData;
        import flash.utils.getDefinitionByName;
        public class  Parent
        {
                public static var bitmapData:BitmapData;                       
 
                public static function initChild(name:String):void
                {
                        var cl:Class = getDefinitionByName(name) as Class;
                        var b:Bitmap = new cl["pic"]();
                        cl.bitmapData = b.bitmapData;
                }
        }       
}

Код AS3:

package 
{
        import flash.display.BitmapData;
        public class  Child1 extends Parent
        {
                [Embed(source = '../lib/explosionDraftPlanet1.png')]
                public static var pic:Class;
 
                public function Child1():void{}
        }
}

Код AS3:

package 
{
        import flash.display.BitmapData;
        public class  Child2 extends Parent
        {
                [Embed(source = '../lib/ExpCloud1.png')]
                public static var pic:Class;
 
                public function Child2():void{}
        }       
}

Результаты трейса: null, 97, 40

Добавлено через 5 минут
Пытаясь разобраться с тем, что происходит, я пришёл к следующей теории:
static переменные не наследуются, а приведённый пример работает из-за того, что в результате всех этих махинаций с definitionByName и т.п. соответствующие поля были добавлены в классы-потомки, но изначально их там не было унаследовано.

goodguy 07.07.2011 10:02

Цитата:

Я провёл тестирование наследования static переменной. Результат: при большом желании она наследуется.
Напишите об этом в адоби. Скажите им, что они дураки.

п.с. я не вижу в этом коде подтверждения того, что статичные переменный наследуются.

AirDecade 07.07.2011 10:06

Цитата:

Сообщение от goodguy (Сообщение 1009471)
Напишите об этом в адоби. Скажите им, что они дураки.

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


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

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