使用 getdefinitionbyname 后访问属性

Accessing properties after using getdefinitionbyname

我正在尝试从 class 访问属性,如下所示:

public class Oak extends Tree //base class for tree classes
{
    public static const CLASS_NAME:String = getQualifiedClassName(Oak);

    public var branches:Array;

    public function Oak() 
    {
        branches = 
        [
        "Leaf1",
        "Leaf2",
        ];
    }

尝试访问变量的 class 显示如下:

public class TreeTest extends BaseScreen //just extends Sprite, TreeTest is shown on the stage
{
    public var oak:Tree;

    private var inc:int;

    public function TreeTest(pModel:Model) 
    {
        model = pModel;

        model.createTree(Oak.CLASS_NAME);
        oak = model.getTree(Oak.CLASS_NAME);
        inc = 0;

        this.addMouseClickListener(0, treeHandler); //from BaseScreen
    }

    private function treeHandler(e:MouseEvent):void 
    {
        inc++;
        this.displayText.text = oak.branches[inc];
    }

型号如下:

public class Model 
{
    public var treeArray:Array;

    public function Model() 
    {
        treeArray = new Array();
    }

    public function createTree(pClassName:String):void 
    {
        var name:String = pClassName;
        var ClassReference:Class = getDefinitionByName(name) as Class;
        var classInstance:Tree = new ClassReference;
        treeArray.push([name, classInstance]);
    }

    public function getTree(pClassName:String):Tree
    {
        var treeName:String = pCharacterClassName;
        var match:Boolean = false;
        var matchArrayRef:int = 0;

        for (var i:int = 0; i < treeArray.length; i++) 
        {
            if (match == true) 
            {
                break
            }

            if (treeArray[i][0] == treeName) 
            {
                match = true;
                matchArrayRef = i;
            }
            else 
            {
                match = false;
            }
        }

        if (match == false) 
        {
            return null; 
        }
        else 
        {
            return treeArray[matchArrayRef][1];
        }
    }

当我 运行 执行此操作时,出现错误 "Access of possibly undefined property branches through a reference with static type Tree"。

在搜索解决方案后,我发现基本上意味着 b运行ches 数组不在树 class 中。为了证实这一点,如果我去把 public var branches:Array 从橡树 class 上拿走,然后把它放在树 class 中,代码就可以工作了。

为什么我不能访问 Oak class 中定义的变量,而必须将所有内容都放在 Tree 基 class 中?即使我将 var classInstance:Tree 更改为 var classInstance:Oak,甚至 var classInstance:Object,如果数组在 Oak class 而不是 Tree class.

比如,如果我创建一个新的 class Pine,它也会扩展 Tree,我是否也必须将 Pine 的所有变量都放在树 class 中?

您将 oak 变量引用为 class Tree,因此您从中引用的任何 属性 都应该是 class Tree, 不是任何 subclasses,因为恰好 superclass 没有它们,因此编译器不知道如何从 branches 属性 寻址内存。更糟糕的是,这种寻址在技术上可能不同于 subclass 和 subclass,这就是为什么通过 superclass 类型的引用直接寻址 subclass 的属性是不可能的。

有一个解决方法。你可以使用Objectclass中定义的hasOwnProperty方法来检查某棵树是否有branches,然后通过tree["branches"]等基于字符串的寻址来寻址。

if (tree.hasOwnProperty("branches")) {
    var br=tree["branches"];
    trace(br); //or whatever
}

其实你甚至可以这样走:

if (tree is Oak) {
    var oak:Oak=tree as Oak;
    // now all oaks have branches, go get em
    trace(oak.branches);
}

不过,这违反了面向对象编程的核心原则之一 - 您试图明确依赖子class具有特定名称变量的 es,并期望它们在子[中包含相同含义的值=39=]es。或者,使用第二种方法,您试图让代码知道 Tree 的每个子 class 将永远存在。实际上,您试图让 subclasses 表现得像 superclass,而没有给 superclass 足够的属性来以通用方式提供该行为。这不是 OOP 的工作方式。因此,您应该首先设计一个 superclass,通过为它分配 genericTree 的属性和方法。万树皆有枝,所以branches应该属于Treeclass。例如,所有树木都可以 grow(),无论提供给生长的任何参数集,湿度、温度、土壤厚度等,但它们对于 [=13= 的所有子 class 都是相同的],无论是橡树还是红杉,因此,grow() 方法也应该属于 Tree class。然而,它们的生长方式不同,对参数的响应也不同,但这正是 override 帮助在 subclasses 中提供不同行为的地方。