无法从另一个对象访问对象属性
Cannot access objects properties from another object
关于这个有很多问题,所以想知道我是否真的无法访问其他对象。
假设我有一枚导弹 class.
public class Missile extends MovieClip {
...
public function update(e:Event) {
x += speed;
if (notInScreen()) this.remove();
for (var i in Main.instance.enemies) {
if (hitTestObject(Main.instance.enemies[i])) {
Main.instance.enemies[i].explode();
this.remove();
}
}
}
public function remove() {
this.parent.removeChild(this);
ship.missiles.splice(0,1); // <--- error
}
}
当它调用 remove() 函数时,它会尝试访问 Ship class,我已将 Ship 放在舞台上并命名其实例 ship
。但我仍然收到错误 1120:访问未定义的 属性 ship.
飞船包含导弹阵列
public class Ship extends MovieClip {
public var missiles:Array;
并且 Main 包含敌人数组
public class Main extends MovieClip {
public var enemies:Array;
但是 Main.instance.enemies
有效,这是否意味着 Main 不被视为对象,因为它只是一个文档?
或者有没有办法解决这个问题?
我不确定您为什么可以执行“Main.instance.enemies”,但是,您需要访问舞台。
你可以通过几种方式做到这一点:
第一种方式:从显示对象访问时:
this.parent;
第二种方式:从 class:
的实例访问时
this.root.stage
第三种方式:将阶段推为 class 实例的参数:
var class:Class1=new Class1(stage);
在 class:
public class class1{
var mainStage:object;
public function class1(stage:Object){
mianStage=stage;
}
我 H☺ P E 这有帮助!
当然你会得到那个错误,因为在你的 Missile
class 里面你不能像那样访问舞台上的对象。
要使用您的 ship
对象,您可以这样做:
MovieClip(root).ship.missiles.splice(0, 1);
或者,如果你的Missile
被添加到舞台上,你可以这样写:
MovieClip(this.parent).ship.missiles.splice(0, 1);
希望能帮到你。
简而言之,您的做法是错误的做法。 Missile
对象不关心在它销毁自身之前从存储它的某些数据结构中删除自身。我将在下面进一步解释如何做,但首先要回答你的问题:
为什么那一件事不起作用
when it calls remove()
function it tries to access a Ship
class, I have placed Ship on stage and named its instance ship
.
不,它不访问 Ship
class。
- 将一艘船放在舞台上会创建一个 该 class 的对象。
- 给它一个实例名称会在后台创建一个变量,即对对象的引用。
也许您只是在提问时不知道正确的术语。但是理解对象和 classes.
之间的区别实际上很重要
如果有的话,您正在尝试访问 Ship
class 的对象,而不是 class 本身。但是,问题仍然是为什么它不起作用。答案就是范围。使用实例名称 ship
自动声明的变量在主时间轴上声明(Main
class)。这与 Missile
class 是分开的。
看看你用 missiles
数组做了什么:
你在Ship
class:
声明
public class Ship extends MovieClip {
public var missiles:Array;
那么您正试图在 class:
的对象上访问它
ship.missiles
现在您认为 ship
本身为什么不同?您也不希望直接访问 missiles
!就像你 missiles
在某个对象中,你需要那个对象才能到达 missiles
,同样适用于 ship
本身:你需要它所在的对象才能到达访问它。
你基本上是在问"Hey, I give me the missiles of the ship!",答案是"What ship?",因为不清楚你指的是什么船。您从未在 Missile
class 中声明变量 ship
。 你在你的脑海中创建了一个快捷方式,它应该以某种方式访问主时间线上的ship
变量,但它们是完全独立的。在项目中使用相同的名称可能会使您陷入此类谬误。您不妨尝试在您的 Missile
class 中访问 bananas
,这也不起作用,但更明显的是它是其他东西。
为什么其他东西有效
But Main.instance.enemies
works, does that mean Main
is not considered object, because it's just a document?
没有"just a document"这样的东西。 Main
只是另一个 class。用作文档时有一些特殊性class,但这里不重要
Main.instance.enemies
起作用的原因如下。
正如我上面解释的,变量存在于对象中(反过来又可以被存在于对象中的变量引用)
因此您需要一个对象的引用才能访问其中的变量。从它派生的对象的 Missile
class 和因此 none 具有此引用。 (是的,这正是错误所说的)。
问题是:如何以某种方式将对 ship
对象的引用获取到 Missile
对象中?
一种不错的方法是传递对 Missile
构造函数的引用:
public class Missile extends MovieClip
{
private var ship:Ship;
public function Missile(ship:Ship)
{
// error handling when ship is null is omitted here
this.ship = ship;
}
当您创建 Missile
class 的实例时,您将 ship
的实例传递给它:
var missile:Missile = new Missile(ship);
disclaimer the following is to explain what's going on in your code. Just to be clear: this is very bad coding practice. You should never do it this way. The important thing to understand is not how it works. The important thing to understand is why it's bad.
有 static
关键字。在整个答案中,必须通过从 class.
创建的对象访问 class 定义的所有变量
如果变量是 static
,则它不与对象相关联,而是与 class 本身相关联。如果某些东西不能真正与单个对象相关联,这将非常有趣,例如常量:
Math.PI
MouseEvent.MOUSE_DOWN
每个对象不必存在一次。由于 class 的 static
变量与 class 而不是其对象相关联,因此您可以通过 class 名称访问此 static
变量。
这就是另一条线发挥作用的地方:
Main.instance
instance
通过 class 名称访问,这意味着它是一个 static
变量。这意味着 Main
class 有一个静态变量(或者也可能是一个函数),它持有对其对象之一的引用。
通过 static
机制,对对象的引用变得全局可用,因为 class 名称随处可用。
这就是如何偷偷地将一个对象的引用放到它实际上不应该出现的地方。
这是该解决方案不好的部分。全球可用的东西没有很好地封装。每个人都可以访问和修改它,这会导致滥用。
怎么做
同样,问题是您需要引用某个对象才能对其进行操作,例如进行碰撞检测。
最好的办法是首先了解什么属于哪里。虽然 Ship
class 有一个包含所有 missiles
的数组是可以理解的,但在 Main
中也有一个数组要容易得多。那是因为导弹对象本身是独立于飞船的,而且无论如何它们都会被添加到主时间线中。
public class Main extends MovieClip {
private var missiles:Array;
private var enemies:Array;
如果你仔细想想,船和导弹之间唯一真正的联系是船是它们产生的地方。
现在您可以轻松地从 Main
class 生成新的 Missile
对象并将这些对象输入数组。
最重要的是,您现在将两个阵列放在一个地方,并且可以在Main
中进行碰撞检测。没有更多关于什么代码应该放在哪里的混淆(敌人应该测试导弹还是导弹测试敌人?)这一切都发生在所有对对象的引用都容易获得的地方。没有滥用 static
.
关于这个有很多问题,所以想知道我是否真的无法访问其他对象。
假设我有一枚导弹 class.
public class Missile extends MovieClip {
...
public function update(e:Event) {
x += speed;
if (notInScreen()) this.remove();
for (var i in Main.instance.enemies) {
if (hitTestObject(Main.instance.enemies[i])) {
Main.instance.enemies[i].explode();
this.remove();
}
}
}
public function remove() {
this.parent.removeChild(this);
ship.missiles.splice(0,1); // <--- error
}
}
当它调用 remove() 函数时,它会尝试访问 Ship class,我已将 Ship 放在舞台上并命名其实例 ship
。但我仍然收到错误 1120:访问未定义的 属性 ship.
飞船包含导弹阵列
public class Ship extends MovieClip {
public var missiles:Array;
并且 Main 包含敌人数组
public class Main extends MovieClip {
public var enemies:Array;
但是 Main.instance.enemies
有效,这是否意味着 Main 不被视为对象,因为它只是一个文档?
或者有没有办法解决这个问题?
我不确定您为什么可以执行“Main.instance.enemies”,但是,您需要访问舞台。
你可以通过几种方式做到这一点:
第一种方式:从显示对象访问时:
this.parent;
第二种方式:从 class:
的实例访问时this.root.stage
第三种方式:将阶段推为 class 实例的参数:
var class:Class1=new Class1(stage);
在 class:
public class class1{
var mainStage:object;
public function class1(stage:Object){
mianStage=stage;
}
我 H☺ P E 这有帮助!
当然你会得到那个错误,因为在你的 Missile
class 里面你不能像那样访问舞台上的对象。
要使用您的 ship
对象,您可以这样做:
MovieClip(root).ship.missiles.splice(0, 1);
或者,如果你的Missile
被添加到舞台上,你可以这样写:
MovieClip(this.parent).ship.missiles.splice(0, 1);
希望能帮到你。
简而言之,您的做法是错误的做法。 Missile
对象不关心在它销毁自身之前从存储它的某些数据结构中删除自身。我将在下面进一步解释如何做,但首先要回答你的问题:
为什么那一件事不起作用
when it calls
remove()
function it tries to access aShip
class, I have placed Ship on stage and named its instanceship
.
不,它不访问 Ship
class。
- 将一艘船放在舞台上会创建一个 该 class 的对象。
- 给它一个实例名称会在后台创建一个变量,即对对象的引用。
也许您只是在提问时不知道正确的术语。但是理解对象和 classes.
之间的区别实际上很重要如果有的话,您正在尝试访问 Ship
class 的对象,而不是 class 本身。但是,问题仍然是为什么它不起作用。答案就是范围。使用实例名称 ship
自动声明的变量在主时间轴上声明(Main
class)。这与 Missile
class 是分开的。
看看你用 missiles
数组做了什么:
你在
声明Ship
class:public class Ship extends MovieClip { public var missiles:Array;
那么您正试图在 class:
的对象上访问它ship.missiles
现在您认为
ship
本身为什么不同?您也不希望直接访问missiles
!就像你missiles
在某个对象中,你需要那个对象才能到达missiles
,同样适用于ship
本身:你需要它所在的对象才能到达访问它。
你基本上是在问"Hey, I give me the missiles of the ship!",答案是"What ship?",因为不清楚你指的是什么船。您从未在 Missile
class 中声明变量 ship
。 你在你的脑海中创建了一个快捷方式,它应该以某种方式访问主时间线上的ship
变量,但它们是完全独立的。在项目中使用相同的名称可能会使您陷入此类谬误。您不妨尝试在您的 Missile
class 中访问 bananas
,这也不起作用,但更明显的是它是其他东西。
为什么其他东西有效
But
Main.instance.enemies
works, does that meanMain
is not considered object, because it's just a document?
没有"just a document"这样的东西。 Main
只是另一个 class。用作文档时有一些特殊性class,但这里不重要
Main.instance.enemies
起作用的原因如下。
正如我上面解释的,变量存在于对象中(反过来又可以被存在于对象中的变量引用)
因此您需要一个对象的引用才能访问其中的变量。从它派生的对象的 Missile
class 和因此 none 具有此引用。 (是的,这正是错误所说的)。
问题是:如何以某种方式将对 ship
对象的引用获取到 Missile
对象中?
一种不错的方法是传递对 Missile
构造函数的引用:
public class Missile extends MovieClip
{
private var ship:Ship;
public function Missile(ship:Ship)
{
// error handling when ship is null is omitted here
this.ship = ship;
}
当您创建 Missile
class 的实例时,您将 ship
的实例传递给它:
var missile:Missile = new Missile(ship);
disclaimer the following is to explain what's going on in your code. Just to be clear: this is very bad coding practice. You should never do it this way. The important thing to understand is not how it works. The important thing to understand is why it's bad.
有 static
关键字。在整个答案中,必须通过从 class.
如果变量是 static
,则它不与对象相关联,而是与 class 本身相关联。如果某些东西不能真正与单个对象相关联,这将非常有趣,例如常量:
Math.PI
MouseEvent.MOUSE_DOWN
每个对象不必存在一次。由于 class 的 static
变量与 class 而不是其对象相关联,因此您可以通过 class 名称访问此 static
变量。
这就是另一条线发挥作用的地方:
Main.instance
instance
通过 class 名称访问,这意味着它是一个 static
变量。这意味着 Main
class 有一个静态变量(或者也可能是一个函数),它持有对其对象之一的引用。
通过 static
机制,对对象的引用变得全局可用,因为 class 名称随处可用。
这就是如何偷偷地将一个对象的引用放到它实际上不应该出现的地方。
这是该解决方案不好的部分。全球可用的东西没有很好地封装。每个人都可以访问和修改它,这会导致滥用。
怎么做
同样,问题是您需要引用某个对象才能对其进行操作,例如进行碰撞检测。
最好的办法是首先了解什么属于哪里。虽然 Ship
class 有一个包含所有 missiles
的数组是可以理解的,但在 Main
中也有一个数组要容易得多。那是因为导弹对象本身是独立于飞船的,而且无论如何它们都会被添加到主时间线中。
public class Main extends MovieClip {
private var missiles:Array;
private var enemies:Array;
如果你仔细想想,船和导弹之间唯一真正的联系是船是它们产生的地方。
现在您可以轻松地从 Main
class 生成新的 Missile
对象并将这些对象输入数组。
最重要的是,您现在将两个阵列放在一个地方,并且可以在Main
中进行碰撞检测。没有更多关于什么代码应该放在哪里的混淆(敌人应该测试导弹还是导弹测试敌人?)这一切都发生在所有对对象的引用都容易获得的地方。没有滥用 static
.