views:

49

answers:

3

Hey guys,

I am hoping someone can explain about subclasses accessing variables from the super class.

I found that the subclass can only access variables which are set in the constructor of the super class. Is there any way around 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){
   test_declared_late = "declared late";
   knight = new Knight("matt");
  }

 }

I try to access the strings in the subclass, but can only get one:

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
  }

 }

}

My entire test project can be found here: http://www.mediafire.com/?46zwpfo4h47cdaq

Thanks!

A: 

Hi there,

There are a couple of things to note here, Firstly, when accessing a property of a super class, you don't need to do:

super.test_declared_early

Rather just:

test_declared_early

Secondly, the reason test_declared_late is null, is that all Strings have a default value of null. You haven't assigned it a value yet! init must be called, or you need to set it manually.

Happy coding!

Tyler Egeto
A: 

Thanks for the tip about not needing super.

However, I didn't make this clear, but another part of the program calls init:

In the GameScreen class:

_character.init(this);

Putting a trace before

test_declared_late = "declared late";

shows it is called. Plus, if init was not called, the code would not get to the knight constructor.

If you had time I would really appreciate it if you could checkout the source http://www.mediafire.com/?46zwpfo4h47cdaq

Thanks!

Casey87
The problem is you are tracing out 'test_declared_late' before init gets called. Trace happens in Constructor, init happens after.
Tyler Egeto
A: 

I'm almost positive I am tracing it out after init is called. Here I added a few traces, and show the code where I am calling init:

GameScreen class calls 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);
        }
    }

}

Character class:

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 subclass:

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
        }

    }

}

The output of all this is:

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

Maybe I'm not understanding what you, but it still looks like I am calling init and setting the variable before I trace it out in the subclass.

Thanks for your help!

Casey87
I think there is a fundamental misunderstanding here. 'test_declared_late' is a property of every instance of your class. Everytime you use the 'new' keyword, a new object instance is created. Every object has its own 'test_declared_late' value. You called init on _character, but not on Knight. It is impossible for the value to be set in Knight constructor, unless it has a default value, like test_declared_early does. You could call init from Knights constructor before the trace happens.
Tyler Egeto
Ahh...Thanks for hanging with me. I was completely confused about what Knight actually was. I didn't realize that the properties for the characters were not shared. So if I have a Knight and a King, they have their own individual 'test_declared_late' properties.Thanks again!
Casey87
No problem, good luck
Tyler Egeto