AS3 доступ к переменным суперкласса из подкласса - PullRequest
0 голосов
/ 16 августа 2010

Я надеюсь, что кто-то может объяснить, как подклассы обращаются к переменным из суперкласса.

Я обнаружил, что подкласс может обращаться только к переменным, которые установлены в конструкторе суперкласса. Есть ли способ обойти это?

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 ]

1 голос
/ 16 августа 2010

Здесь следует отметить пару вещей: во-первых, при доступе к свойству суперкласса вам не нужно делать:

super.test_declared_early

Скорее всего:

test_declared_early

Во-вторых, причиной test_declared_late является null, потому что все строки имеют значение по умолчанию null. Вы еще не присвоили ему значение! init должен быть вызван, или вам нужно установить его вручную.

Удачного кодирования!

0 голосов
/ 04 сентября 2012

Я действительно рекомендую вам проверить, что означают private , protected и public . Я не буду писать книгу о ООП в этом посте, поэтому я рекомендую вам проверить основы.

Что я сделаю, я дам вам пример того, как использовать и объявлять переменные.

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();
0 голосов
/ 17 августа 2010

Я почти уверен, что выслеживаю его после вызова 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");
        }

    }

}

Knightподкласс:

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 и устанавливаю переменную передЯ прослеживаю это в подклассе.

Спасибо за вашу помощь!

0 голосов
/ 16 августа 2010

Спасибо за подсказку о том, что супер не нужен.

Однако я не прояснил это, но другая часть программы вызывает init:

В классе GameScreen:

_character.init(this);

Помещение трассировки перед

test_declared_late = "declared late";

показывает, что она вызывается.Кроме того, если init не был вызван, код не попал бы в конструктор рыцаря.

Если бы у вас было время, я был бы очень признателен, если бы вы могли проверить источник http://www.mediafire.com/?46zwpfo4h47cdaq

Спасибо!

...