2010-08-16 141 views
-1

我希望有人可以解释有关访问超类的变量的子类。AS3访问子类的超类变量

我发现子类只能访问在超类的构造函数中设置的变量。有没有办法解决?

package Character { 

import flash.display.MovieClip; 

public class Character extends MovieClip { 
    protected var test_declared_early:String = "declared early"; 
    protected var test_declared_late:String; 

    private var knight:Knight; 

    public function Character() { 
    // constructor code 
    } 

    public function init(_local_stage:Object){ 
    test_declared_late = "declared late"; 
    knight = new Knight("matt"); 
    } 

} 

我尝试访问子类中的字符串,但只能得到一个:

package Character{ 

public class Knight extends Character.Character { 

    private var myName:String; 

    public function Knight(local_name:String) { 
    // constructor code 
    myName = local_name; 
    trace(super.test_declared_early); //this is not null 
    trace(super.test_declared_late); //this is null 
    } 

} 

} 

我的整个测试项目可以在这里找到: http://www.mediafire.com/?46zwpfo4h47cdaq

谢谢!

回答

1

有一对夫妇的事情,这里要注意,首先,访问一个超类的属性时,你不需要做:

super.test_declared_early 

而只是:

test_declared_early 

其次,test_declared_late为null的原因是,所有字符串的默认值为null。你还没有分配它的价值!必须调用init,否则您需要手动设置它。

编码愉快!

-1

感谢关于不需要超级的提示。

不过,我并没有明确这一点,但该计划的另一部分调用init:

在GameScreen类:前

_character.init(this); 

把一丝

test_declared_late = "declared late"; 

显示它被称为。另外,如果init没有被调用,代码就不会到达骑士构造函数。

如果你有时间,我真的很感激,如果你能签出源 http://www.mediafire.com/?46zwpfo4h47cdaq

谢谢!

+0

问题是你在init被调用之前正在追踪'test_declared_late'。跟踪发生在构造函数中,init发生之后。 – 2010-08-16 20:05:43

0

我几乎是积极的我在调用init之后追踪它。在这里,我增加了一些痕迹,表明这里我呼吁初始化代码:

GameScreen类调用init:

package 
{ 
    import flash.display.MovieClip; 

    public class GameScreen extends MovieClip 
    { 

     public var docClass:Test; 
     public function GameScreen(passed_class:Test) 
     { 
      // constructor code 
      docClass = passed_class; 
      trace("call init"); 
      _character.init(this); 
     } 
    } 

} 

字符类别:

package Character { 

    import flash.display.MovieClip; 

    public class Character extends MovieClip { 
     protected var test_declared_early:String = "declared early"; 
     protected var test_declared_late:String; 

     private var knight:Knight; 

     public function Character() { 
      // constructor code 
     } 

     public function init(_local_stage:Object){ 
      trace("setting late variable"); 
      test_declared_late = "declared late"; 
      trace("construct a knight"); 
      knight = new Knight("matt"); 
     } 

    } 

} 

骑士子类:

package Character{ 

    public class Knight extends Character.Character { 

     private var myName:String; 

     public function Knight(local_name:String) { 
      // constructor code 
      myName = local_name; 
      trace("in knight constructor, early= " + test_declared_early); //this is not null 
      trace("in knight constructor, late= " +test_declared_late); //this is null 
     } 

    } 

} 

所有这些的输出是:

call init 
setting late variable 
construct a knight 
in knight constructor, early= declared early 
in knight constructor, late= null 

也许我不理解你,但它仍然看起来像我调用init并设置变量,然后再在子类中找到它。

感谢您的帮助!

+1

我认为这里有一个根本性的误解。 'test_declared_late'是你类的每个实例的属性。每次使用'new'关键字时,都会创建一个新的对象实例。每个对象都有自己的'test_declared_late'值。你在_character上调用init,但不在Knight上调用。在Knight构造函数中设置该值是不可能的,除非它具有默认值,比如test_declared_early。在跟踪发生之前,您可以从Knights构造函数调用init。 – 2010-08-16 20:48:22

+0

啊......谢谢你和我挂在一起。我对奈特实际上是什么感到困惑。我没有意识到角色的属性不共享。所以如果我有骑士和国王,他们有自己的'test_declared_late'属性。 再次感谢! – Casey87 2010-08-16 20:55:10

+0

没问题,祝你好运 – 2010-08-16 22:14:24

-1

我真的建议你检查什么私人保护公共手段。 我不会在这篇文章中写一本关于OOP的书,所以我想请你检查一下基本知识。

我会做什么我会给你一个关于如何使用和声明变量的示例。

class A 
{ 
    private var _password:String; 
    public var username:String; 
    protected var serverURL:String; 

    public function login():void 
    { 
     // some code 
     callServerForLogin(); 
    } 

    protected function callServerForLogin():void 
    { 
     // some code 
    } 
} 

class B extends A 
{ 
     public function B() 
     { 
      var parentPassword = super._password; 
      // FAILS because private and accessible only inside class A 

      var parentUsername = super.username 
      // all ok in here, public property 

      var parentServerURL = super.serverURL; 
      // all ok, because it is protected 

      // also we can call super.login(); or super.callServerForLogin(); 

     } 

     // IMPORTANT we are also allowed to override public and protected functions 
     override public function login():void 
     { 
      super.login(); 
      // we call the parent function to prevent loosing functionality; 

      Alert.show("Login called from class B"); 
     } 

     override protected function callServerForLogin():void 
     { 
      super.callServerForLogin(); 
      // keep also parent logic 

      Alert.show("calling protected method from B"); 
     } 
} 


// ---- Now considering you declare an object of type B you can do the following 
var bObj:B = new B(); 

// access public properties and call public functions from both B and A 
bObj.username = "superhero"; 
bObj.login(); 

// will get compile error for next lines 
bObj.serverURL = "host.port"; 
bObj.callServerForLogin();