| |
|
||||
|
The Prototype In previous class examples, there were three places to assign properties. You can attach them directly to the class object, like A.temp. You can have temporary properties inside the class block{ }by using var x = 5. Lastly, you can attach properties to the object ("this") that is passing through the class's activation object when an instance is created. These properties will end up in the new instance. This may seem like a lot of ways to set a property, but there is still one thing you cannot do. There is no way to set a property that belongs to the class, but is available to an instance. That probably sounds strange, so let's look closer. Take the very simple Dog class below: Dog = function( ) { this.legs = 4; } rover = new Dog( ); fido = new Dog( ); yeller = new Dog( ); You may feel that the " this.legs" property belongs to the Dog class because it is assigned there. It seems that it is just 'made available' to each instance of Dog but is still part of the class - but that isn't the case. The legs property ends up in the instance object only - there is no way to even get at it if you start from Dog (Dog.instance.legs, Dog.benji.legs, Dog.legs - none of these finds it). Clearly it is not a Dog property, it is an instance property (benji.legs, fido.legs... these are OK). What about if you say Dog.legs = 4? Would it then be a class property that is available to instances? With some trickery, instances can (sometimes) access this property (benji.constructor.legs if you are curious), but is that correct? Should benji have to ask the class that defines Dog how many legs he should have, or should he just know? If we say benji is a type of dog, then benji should have all features common to dogs; that should happen automatically. If we write Dog.legs = 4, benji.legs remains null. What we need to use here is called the prototype object.
Now we can put information about all dogs in the Dog class, and use the instances for information that is specific to each dog. It's just a matter of learning the syntax, which is always the easy part: Dog = function( ){} Dog.prototype.legs = 4; rover = new Dog( ); fido = new Dog( ); yeller = new Dog( ); fido.puffyHair = true; Now things are where they belong - all dogs have four legs, but the puffyHair was a personal lifestyle choice of fido's. That's not to say that other dogs couldn't have the exact same hairstyle, just that it is specific to the individual, not a general feature of dogs. So fido has a puffyHair property, the others don't. They all have a "legs" property, though it comes from Dog.prototype.legs rather than fido.legs. How do you access legs from fido? This is the beauty of it, you access it in just the same way you would access any other property of fido - fido.legs. In fact you don't know, need to know, or want to know where this property came from. That doesn't mean you don't want to put it in the right place and have it stored in the right place when your program runs, just that you want to access it as if it were a property of the instances - rover, fido or yeller. This is all great, but it does poke a few holes in our 'boxes' metaphor that we have been using for objects. Let's clarify then. One can think of objects as boxes with a list of their contents taped to the outside. This still holds true. What is happening inside those boxes however isn't what we would expect from regular cardboard boxes. For this we need a new metaphor.
You can slide things into different layers, however it will appear as if they are all on the first layer. If you slide one paper in front of another (on different layers), you will only see the one closest to you. The front layer of glass is a bit special, in that you can reach it easily. You can make marks to paper that is on the front layer (modify), add new sheets (add), or take sheets off and throw them out (delete). The deeper layers basically stay the way they are once you set them up, unless you really, really want to change them (becasue it is easy to get cut sandwiching and un-sandwiching the layers (dangerous code!) ). Usually, you just make changes by putting new sheets of paper on the front glass (covering the ones further back) and use that sheet to make changes. Under no circumstances are you allowed to draw on the glass! You learned that when you were four. This seems like a lot to remember, but rejoice -Actionscript takes care of every one of these details for you automatically! Look at the two illustrations of glass above - do you see how they line up when brought together? Yellow is on the first layer, orange on the second, and purple on the third. What would you do if you wanted to now modify the center (purple) square? Ans.Tape a new paper to the front - it's too much trouble to take the windows apart. Properties on an object, then, are less like things drawn on a chalkboard and more like things taped to a window. The first (front) window is your instance. It gets properties set on its level when it is 'instanciated' (created). Properties are attached to it (or, specifically, the nameless object that it will become) using the 'this' keyword. After it is created, a property can be attached manually, by saying instance.x=5. We will find there are a few more ways that properties end up on the instance layer. The second sheet of glass contains the properties that belong to the class (the class that made the instance), and they are located in the Class.prototype. Whatever one adds to the second sheet will be seen by all instances created with the class. To go back to the dog example, if we added the puffyHair property to the Dog.prototype (the second sheet of glass), then all three dogs would now have puffy hair. Old yeller, loyal though he is, would probably not be amused.
Inheritance < < Home > > Overriding
|