Форум Flasher.ru

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

zhoran 19.01.2011 18:11

Предок не приводится к наследнику. Почему?
 
Хочу расширить Array. Почитал Мука, посмотрел хелп. Сделал так:
Код AS3:

public dynamic class MyArray extends Array
{
 
  public function MyArray(... args)
  {
 
  }
 
  public function compact():Array {
    var arr:Array = this.filter(
      function (element:*, index:int, arr:Array):Boolean {
        return (element != null);
      })
    return arr;
  }
 
}

А это не работает:
Код AS3:

var my_arr:MyArray = [null, null, 2, 3];
//Пишет: Implicit coercion of a value with static type Array to a possibly
//unrelated type utils:MyArray.
 
var my_arr:MyArray = MyArray ([null, null, 2, 3]);
//Пишет rte: [Fault] exception, information=TypeError: Error #1034:
//Ошибка типа Coercion: невозможно преобразовать []@156d291 в utils.MyArray
 
var my_arr:MyArray = [null, null, 2, 3] as MyArray;
// Не ругается, но my_arr равен null

как можно создать объект MyArray из объекта Array ?
и в чем разница ... as MyArray и MyArray (...) ?

Dukobpa3 19.01.2011 18:55

Код AS3:

public dynamic class MyArray extends Array 
{       
        public function MyArray(... args)
        {
                super();
                for (var i:int = 0 ; i < args.length ; i ++ ) {
                        this.push(args[i]);
                }               
        }       
}

Код AS3:

var arr:MyArray = new MyArray(1, 2, 3, 4);
trace(arr);
//1,2,3,4
 
arr.push(5);
trace(arr);
//1,2,3,4,5
 
arr[5] = 6;
trace(arr);
//1,2,3,4,5,6

А как заставить чтоб работало:
Код AS3:

var arr:MyArray = [1, 2, 3, 4]

Я не знаю:)

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

делай

Код AS3:

public function MyArray(... args)
{
super(args);
}

Нет. не делай;) Этот код всунет тебе в первый элемент массива, тот массив который ты ему вручил в конструкторе.

например если сделаешь вот так:
Код AS3:

var my_arr:MyArray = MyArray ([null, null, 2, 3]);

то получишь такую конструкцию:
Код:

1. [null, null, 2, 3]
а потом если сделаешь к примеру:
Код AS3:

my_arr.push(22);
my_arr.push(33);
my_arr.push(44);

то получится примерно следующее:
Код:

1. [null, null, 2, 3]
2. 22
3. 33
4. 44


zhoran 19.01.2011 19:21

Спасибо за помощь!
Немного переделал, теперь у меня так:

Код AS3:

public dynamic class MyArray extends Array
{
 
  public function MyArray(arr:Array)
  {
    arr.forEach(this.push_element);
  }
 
  private function push_element(element:*, index:int, arr:Array):void {
    this.push(element);
  };
}
 
var my_arr:MyArray = new MyArray([null, null, 2, 3]);


Obi 19.01.2011 19:22

Простите, а с чего массив должен реализовывать методы, объявленные в его наследнике? Вы пишете var arr:MyArray = new Array(). Array не наследует поведение MyArray, в то время как MyArray поведение Array — наследует. Следовательно, вот так будет работать: var arr:Array = new MyArray(); а так: var arr:MyArray = new Array() — нет.

zhoran 19.01.2011 19:25

Простите, а с чего массив должен реализовывать методы, объявленные в его наследнике?

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

BlooDHounD 19.01.2011 19:48

Код AS3:

public dynamic class MyArray extends Array {
        public function MyArray(...args) {
                super();
                super.push.apply( null, args );
        }
}


semenyakinVS 19.01.2011 19:58

Потому, что нельзя
 
Потому, что это противоречит концепции ООП. Предок в принципе не может приводиться к наследнику. А сделать так, как вы желаете нельзя.

Код AS3:

var testMyArr:MyArr = [1, 2, 3];   <=>   var testMyArr:MyArr = new Array(1, 2, 3);

Вот если бы в AS3 можно было перегружать операторы, или были бы макросы - пожалуйста... Хотя, и тогда не совсем.

Dukobpa3 19.01.2011 20:02

Код AS3:

  public function MyArray(arr:Array)
  {
    arr.forEach(this.push_element);
  }

Вот этого делать необязательно. "args" - уже и так сам по себе массив. можно писать вот так:
Код AS3:

  public function MyArray(... args)
  {
    args.forEach(this.push_element);
  }

ну и BlooDHounD поизящнее метод предложил, вне конкуренции:)

zhoran 19.01.2011 20:05

Цитата:

Сообщение от BlooDHounD (Сообщение 965960)
Код AS3:

super.push.apply( null, args );


Это круто! И при этом инициализация делается вот так:
Код AS3:

var my_arr:MyArray = new MyArray(null,null,2,3);

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

Сообщение от Dukobpa3 (Сообщение 965969)
Вот этого делать необязательно. "args" - уже и так сам по себе массив.

точно

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

Сообщение от semenyakinVS (Сообщение 965966)
Потому, что это противоречит концепции ООП. Предок в принципе не может приводиться к наследнику.

Это понятно, но согласитесь, в простом случае, когда конструктор явно не объявлен в наследнике (компилятору известно, что новых переменных экземпляра нет), казалось бы чисто технически ничто не мешает реализовать в компиляторе такое приведение предка к потомку. Просто прикрутить к даным экземпляра расширенную потомком таблицу методов. ?

semenyakinVS 19.01.2011 20:19

Цитата:

Сообщение от Dukobpa3 (Сообщение 965941)
Код AS3:

var arr:MyArray = new MyArray(1, 2, 3, 4);
 
arr[5] = 6;
trace(arr);
//1,2,3,4,5,6


Оператор [] будет работать в таком случаи? Это хорошо...

Dukobpa3 19.01.2011 20:24

Цитата:

Оператор [] будет работать в таком случаи?
Будет, код рабочий.
Только с одним условием, оператор new использовать обязательно. Неявная инстанциация как в случае с массивом не получится.

BlooDHounD 19.01.2011 21:12

@Dukobpa3, что такое "неявная инстанциация"?

Dukobpa3 19.01.2011 21:14

хз))) сам придумал.

Короче инстанциировать в любом случае надо руками, это всё что я хотел сказать.

semenyakinVS 19.01.2011 21:22

Не... Я про new понял.

А как Flash догадается привести к типу Array? Если у нас, например, класс наследовал бы другой класс без индексатора, как бы себя повёл код:

Код AS3:

//class smth extends withoutIndexer
 
var test:smth =new smth();
 
smth[1] = 10;

Вот такое - как сработает?

Dukobpa3 19.01.2011 21:29

Если класс динамик, то создаст поле с именем указанным в скобочках
Только не знаю как оно себя поведет если будет число, но во всяком случае если динамик классу сделать:

Код AS3:

smth["something"] = 10;

То у класса появится поле с именем something и значением 10. (В кавычках - значит строка)

Ну а если класс не динамик, будет материться на невозможность создать поле в статическом классе.

Добавлено через 2 минуты
Собственно поэтому класс расширяющий Array у нас динамический, ибо ему поля постоянно новые добавляются, с индексами.

zhoran 19.01.2011 21:45

Цитата:

Сообщение от Dukobpa3 (Сообщение 965997)
Если класс динамик, то создаст поле с именем указанным в скобочках
Только не знаю как оно себя поведет если будет число...

Видимо приведет число к строке и создаст свойство, и [] видимо тоже приводит к строке, т.к.
Код AS3:

var obj:Object = new Object;
 
obj[1] = 2;
trace(obj[1]); // дает 2
trace(obj["1"]); // тоже дает 2


semenyakinVS 19.01.2011 23:42

Цитата:

Сообщение от Dukobpa3 (Сообщение 965997)
Ну а если класс не динамик, будет материться на невозможность создать поле в статическом классе.

Ух ты!.. А как делать статические в таком смысле классы? Там какое-то слово-модификатор перед классом?

И какая от них польза? Даёт прирост оптимизации?

Dukobpa3 20.01.2011 00:05

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

Статические классы по умолчанию, для динамик класса нужно слово "dynamic" указывать.
Кроме динамика есть еще три вида классов. Это и много другое можно прочесть в упомянутых мануалах, не ленитесь.


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

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