2010-08-16 144 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();