使用 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 的属性是不可能的。
有一个解决方法。你可以使用Object
class中定义的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
应该属于Tree
class。例如,所有树木都可以 grow()
,无论提供给生长的任何参数集,湿度、温度、土壤厚度等,但它们对于 [=13= 的所有子 class 都是相同的],无论是橡树还是红杉,因此,grow()
方法也应该属于 Tree
class。然而,它们的生长方式不同,对参数的响应也不同,但这正是 override
帮助在 subclasses 中提供不同行为的地方。
我正在尝试从 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 的属性是不可能的。
有一个解决方法。你可以使用Object
class中定义的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
应该属于Tree
class。例如,所有树木都可以 grow()
,无论提供给生长的任何参数集,湿度、温度、土壤厚度等,但它们对于 [=13= 的所有子 class 都是相同的],无论是橡树还是红杉,因此,grow()
方法也应该属于 Tree
class。然而,它们的生长方式不同,对参数的响应也不同,但这正是 override
帮助在 subclasses 中提供不同行为的地方。