在Actionscript 3(Flex)中扩展数组

8

我需要制作一个特定目的的数组变体。当我有以下内容时:

public class TileArray extends Array {
   // Intentionally empty - I get the error regardless
}

为什么我不能这样做?

var tl:TileArray = [1,2,3];

尽管我能做到这一点,但仍需注意以下事项。
var ar:Array = [1,2,3];

我收到的错误信息是这样的:
隐式强制将静态类型为Array的值转换为可能不相关的类型。

5
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/Array.html 中提到:“您可以扩展 Array 类并覆盖或添加方法。但是,您必须将子类指定为 dynamic,否则您将失去在数组中存储数据的能力。” - Amarghosh
3个回答

13

你可以编写自己的类,公开Array的所有方法,而不是扩展Array。通过使用代理类,你可以将所有默认的数组方法重定向到内部数组,但仍然具有添加自己的方法的灵活性:

package
{
    import flash.utils.flash_proxy;
    import flash.utils.Proxy;

    use namespace flash_proxy;

    dynamic public class ExampleArray extends Proxy
    {
        private var _array:Array;

        public function ExampleArray(...parameters)
        {
            _array = parameters;
        }

        override flash_proxy function callProperty( name:*, ...rest):* 
        {
            return _array[name].apply(_array, rest);

        }

        override flash_proxy function getProperty(name:*):* 
        {
            return _array[name];
        }

        override flash_proxy function setProperty(name:*, value:*):void 
        {
            _array[name] = value;
        }

        public function getSmallestElement():*
        {
            var helper:Array = _array.concat().sort();
            return helper[0];
        }

    }
}
例子:
var test:ExampleArray = new ExampleArray(8,7,6,5,4,3,2,1);
trace( test.getSmallestElement()); // 1
test.sort();
trace(test); // 1,2,3,4,5,6,7,8 

+1. 我只会添加一个链接到文档的示例,展示这个技术:http://livedocs.adobe.com/flex/2/langref/flash/utils/Proxy.html#includeExamplesSummary - Juan Pablo Califano
不错的干净示例,Quasimondo :) - chamberlainpi

3

[] 只能创建一个数组,不能用来创建一个 Array 的子类。

扩展 Array 新功能的好方法是编写独立的实用函数来操作常规的数组。最重要的是,这将允许您对任何数组执行任何操作,而不仅仅是使用您的子类创建的数组。

以下是包含数组实用程序函数的简单示例类:

package com.example.utils
{
    public class ArrayUtil
    {
        public static function traceArray( array:Array ):void
        {
            trace( array.length, "[" + array + "]" );
        }
    }
}

使用方法:

ArrayUtil.traceArray( [1, 2, 3] ); //output: 3 [1,2,3]

是的,我知道我能做到这一点。我主要是在追求语法糖。 - Jamie Wong
如果您想向数组添加变量和属性,则此方法无法帮助您。 - n4pgamer
作为一个不向数组添加变量和属性的人,这是一种特性,而不是错误。 ;) - Josh Tynjala

1

[1,2,3]new Array(1,2,3)的简写(或语法糖)。有了这个想法,你的代码为什么失败就更明显了。

每个TileArray都是一个Array,因为TileArray扩展了Array,但反过来不成立:并非每个Array都是TileArray。所以,在期望TileArray的地方不能传递Array。那就是你得到编译器错误的原因。

类型转换只会将错误从编译时推迟到运行时,因为你的对象的实际类型是Array,它与TileArray确实无关。

如果你想扩展Array的功能(并且还能添加一些语法糖),你可能需要考虑扩展Proxy,就像先前建议的那样。请记住,它的性能较差,因此如果您计划大量使用此类,则可能不是最佳选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接