AS3从子类访问超类变量

时间:2010-08-16 19:18:24

标签: flash actionscript-3 variables oop subclass

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

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

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

谢谢!

4 个答案:

答案 0 :(得分:1)

这里有几点需要注意,首先,在访问超类的属性时,您不需要这样做:

super.test_declared_early

而不仅仅是:

test_declared_early

其次,test_declared_late为null的原因是所有字符串的默认值为null。您尚未为其分配值!必须调用init,或者您需要手动设置它。

快乐的编码!

答案 1 :(得分:0)

我几乎是肯定的,我在调用init后跟踪它。在这里我添加了一些跟踪,并显示我调用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并在我在子类中追踪它之前设置变量。

感谢您的帮助!

答案 2 :(得分:-1)

感谢您提示不需要超级。

但是,我没有说清楚,但程序的另一部分调用init:

在GameScreen类中:

_character.init(this);

之前设置跟踪
test_declared_late = "declared late";

显示它被调用。另外,如果没有调用init,代码将无法访问knight构造函数。

如果你有时间我会非常感激,如果你能查看来源 http://www.mediafire.com/?46zwpfo4h47cdaq

谢谢!

答案 3 :(得分:-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();