Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Namespaced methods overriding. (http://www.flasher.ru/forum/showthread.php?t=202687)

searinox 01.08.2013 22:15

Namespaced methods overriding.
 
Вопрос касается объявления кастомных неймспесов, создания методов с ними и их переопределение.
Сразу оговорюсь что пользуюсь intellij idea 12+.
Я могу определить методы в своем неймспесе и их использовать внутри класса, в котором они определены, но не могу переопределить их в дочерних классах, так как на них ругается компилятор(синтаксический анализор идеи молчит).
Для примера я привел небольшую иерархию как она не работает.
Есть такая структура:
Код AS3:

package test
{
    public class namespace_1
    {
        public namespace namespace_1;
    }
}
 
package test
{
    public class namespace_2
    {
        public namespace namespace_2;
    }
}
 
package test
{
    import test.namespace_1;
    import test.namespace_2;
 
    public class Class1
    {
        private var mode:Namespace = namespace_1;// понятное дело что в других методах присвоить можем что хотим.
        ....
        protected function action():void
        {
                        ....
                        mode::foo();
        }
 
                namespace_1 function foo():void
                {
                        trace("foo in NS1 operating");
                }
 
                namespace_2 function foo():void
                {
                        trace("foo in NS2 operating");
                }
    }
}
 
package test
{
    import test.namespace_1;
    import test.namespace_2;
 
 
        //uses protected function action() from Class1.
    public class Child1 extends Class1
    {   
 
                // COMPILE TIME ERROR:: Namespace was not found or is not a compile-time constant.
                // If i define use namespace namespace_1 before class declaration error changes to
                // Method marked override must override another method.
                override namespace_1 function foo():void
                {
                        trace("foo from Child1 in NS1 operating");
                }               
    }
 
}
 
 
package test
{
    import test.namespace_1;
    import test.namespace_2;
 
 
        //uses protected function action() from Class1.
    public class Grandchild1 extends Child1
    {   
 
                // COMPILE TIME ERROR:: Namespace was not found or is not a compile-time constant.
                // If i define use namespace namespace_1 before class declaration error changes to
                //Method marked override must override another method.
 
                override namespace_1 function foo():void
                {
                        trace("foo  from Grandchild1 in NS1 operating");
                }
    }
 
}


Пожалуйста помогите разобратся с этой темой, кто шарит.

З.Ы.
Я перешарил весь форум в поисках ответа или годного примера, но его не нашел.
Помню был тред в котором обсуждалась возможность перегрузки методов во флеше и кто-то хвастался как он ловко запилил неймспейсы для использования "своей перегрузки" в своей игрушке( фича изменяла режим работы какой-то внутриигровой хреновины: нормальный и турбо)
В общем если кто-то это помнит или встречал буду очень признателен за ссылку.

wvxvw 01.08.2013 23:07

Сейчас не на чем попробовать, но вообще доступ к члену пространства имен либо через :, либо через ::. Т.е. я бы попробовал:
Код:

override function namespace_1:foo (arguments) { ... }
или
Код:

override function namespace_1::foo (arguments) { ... }

searinox 01.08.2013 23:21

Цитата:

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

override function namespace_1:foo (arguments) { ... }
или
Код:

override function namespace_1::foo (arguments) { ... }

Здесь референс к неймспейсу проходит так как я написал но ты натолкнул меня на одну идею.
Сначала должно идти ключ. слово override, потом неймспейс.
тут пример в конце
http://help.adobe.com/en_US/ActionSc...0204-7f9e.html
Код AS1/AS2:

 flash_proxy override function callProperty(name:*, ...rest):*

Хотя это всеравно не помогает(

Wolsh 02.08.2013 02:44

У меня тоже не получилось заставить наследника видеть объявленные в пакете неймспейсы.
Если в наследнике объявить заново неймспейсы с теми же литералами (uri), то все работает.
Либо объявить неймспейсы в суперклассе, но опять же, прописав литералы руками (поскольку это константы, ссылки на объявленные вовне неймспейсы не сработают, как и ссылки на литералы вовне // строковые константы в отдельном файле).

СлаваRa 02.08.2013 11:48

Вложений: 1
Рабочий пример с переопределением метода область видимости которого определена неймспейсом
Вложение 29870

ТС. немного не правильно подошел к реализации.

searinox 02.08.2013 13:25

Цитата:

Сообщение от СлаваRa (Сообщение 1142558)
Рабочий пример с переопределением метода область видимости которого определена неймспейсом
Вложение 29870

ТС. немного не правильно подошел к реализации.

1) У меня так и не получилось поднять и скомпилить твой проект.
2) Задача была именно в том что бы метод, вызывающий занеймспейсеный метод был в том же классе и наследовался. В общем у тебя структура не такая как описал я в примере.
3) и самое главное - никаких use namespace в классе. заметь что неймспейс может менятся динамически и то что ты написал не подходит.

СлаваRa 02.08.2013 14:04

надеюсь в этот раз я правильно понял.
Код AS3:

package {
        import flash.display.Sprite;
        import flash.events.Event;
 
        /**
        * @author SlavaRa
        */

        public class Main extends Sprite {
 
                use namespace $test_public;
 
 
                public function Main():void {
                        super();
                        var test:Test2 = new Test2();
                        test._namespace1::test();
                        test._namespace2::test();
 
                        const namespaces:Vector.<Namespace> = new <Namespace>[_namespace1, _namespace2];
                        for(var i:int = 0; i < 10; i++) {
                                const ns:Namespace = namespaces[int(Math.random() * namespaces.length)];
                                test.ns::test();
                        }
                }
 
                private var _namespace1:Namespace = $test_namespace1;
                private var _namespace2:Namespace = $test_namespace2;
 
        }
}
 
namespace $test_namespace1 = "$test_namespace1";
namespace $test_namespace2 = "$test_namespace2";
 
class Test {
 
        public function Test() {
                super();
        }       
 
        $test_namespace1 function test():void {
                trace("Test.$test_namespace1::test");
        }
 
        $test_namespace2 function test():void {
                trace("Test.$test_namespace2::test");
        }
 
}
 
class Test2 extends Test {
 
        public function Test2() {
                super();
        }
 
        $test_namespace1 override function test():void {
                trace("Test2.$test_namespace1::test");
                super.$test_namespace1::test();
        }
 
        $test_namespace2 override function test():void {
                trace("Test2.$test_namespace2::test");
                super.$test_namespace2::test();
        }
 
}


searinox 02.08.2013 14:07

Цитата:

Сообщение от Wolsh (Сообщение 1142540)
У меня тоже не получилось заставить наследника видеть объявленные в пакете неймспейсы.
Если в наследнике объявить заново неймспейсы с теми же литералами (uri), то все работает.
Либо объявить неймспейсы в суперклассе, но опять же, прописав литералы руками (поскольку это константы, ссылки на объявленные вовне неймспейсы не сработают, как и ссылки на литералы вовне // строковые константы в отдельном файле).

Если честно я понял все кроме этой части:
Цитата:

Сообщение от Wolsh (Сообщение 1142540)
поскольку это константы, ссылки на объявленные вовне неймспейсы не сработают, как и ссылки на литералы вовне // строковые константы в отдельном файле

В остальном же, костыль работает.
На данном этапе все свелось к 2 костылям:
1) Или в родительском классе сделать метод protected, namespace_1, namespace_2, и в потомках переопределять protected вариант, так как в них юзается только один вариант метода, а не оба.
2) В родителе заново определять неймспейс с теми же литералами(и отказаться от автоматических литералов, которые симпатичнее).

Wolsh 02.08.2013 15:03

Цитата:

Если честно я понял все кроме этой части
В том смысле что в теле класса не получится определить
Код AS3:

public namespace ns1 = test.Namespace1 // package test { public namespace Namespace1 = "ns_1" }
// или
public namespace ns2 = test.NamespacesList.NAMESPACE_2 // строковая константа в классе NamespacesList

что конечно же довольно грустно. Но это особенность компилятора, неймспейсы объявлений методов это константы, они должны быть инициализированы перед компиляцией/в ее процессе, поэтому не могут быть ссылками на члены другого класса.
Хелп говорит, что первый метод должен работать, однако компилятор утверждает что не знает никакого test.Namespace1.
При этом сами методы класса, объявленные с этим же неймспейсом, у него проблем не вызывают((( Явно какой-то баг.

Добавлено через 14 минут
То есть вот так нельзя (не может инициализировать неймспейсы ссылками на объявленные в пакете неймспейсы)
Код AS3:

package test 
{
        public class Class_1
        {
                public namespace ns1 = test.Namespace1;
                public namespace ns2 = test.Namespace2;
 
                public function Class_1() {  }
 
                public function activation(mode:Namespace):void
                {
                        mode::foo();
                }
 
                ns1 function foo():void
                {
                        trace("foo in NS1 operating");
                }
 
                ns2 function foo():void
                {
                        trace("foo in NS2 operating");
                }
        }
}

а так можно
Код AS3:

package test 
{
        public class Class_1
        {
                public function Class_1() {  }
 
                public function activation(mode:Namespace):void
                {
                        mode::foo();
                }
 
                test.Namespace1 function foo():void
                {
                        trace("foo in NS1 operating");
                }
 
                test.Namespace2 function foo():void
                {
                        trace("foo in NS2 operating");
                }
        }
}

и так пожалуйста
Код AS3:

package test 
{
        public class Class_1
        {
                public namespace ns1 = "n1";
                public namespace ns2 = "n2";
 
                public function Class_1() {  }
 
                public function activation(mode:Namespace):void
                {
                        mode::foo();
                }
 
                ns1 function foo():void
                {
                        trace("foo in NS1 operating");
                }
 
                ns2 function foo():void
                {
                        trace("foo in NS2 operating");
                }
        }
}


Babylon 02.08.2013 17:31

Ну у скиннера же есть пример как делать
http://dump.thekeppleeffect.com/NamespaceStrategy.as


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

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