RE: [Flashcoders] Problem extending inherited function
> -Original Message- > From: [EMAIL PROTECTED] > [mailto:[EMAIL PROTECTED] On Behalf > Of Mark Winterhalder > Sent: 21 March 2007 23:41 > To: flashcoders@chattyfig.figleaf.com > Subject: Re: [Flashcoders] Problem extending inherited function > Importance: High > Mark, thank you so much for this, it's *exactly* the kind of thing I was looking for. By far the clearest explanation of how inheritcance works in Flash that I've seen. Now I can go back to doing what I was doing, but with a *much* clearer idea of why things do or don't work. Best Danny ___ Flashcoders@chattyfig.figleaf.com To change your subscription options or search the archive: http://chattyfig.figleaf.com/mailman/listinfo/flashcoders Brought to you by Fig Leaf Software Premier Authorized Adobe Consulting and Training http://www.figleaf.com http://training.figleaf.com
Re: [Flashcoders] Problem extending inherited function
On 3/21/07, Danny Kodicek <[EMAIL PROTECTED]> wrote: Hmm - this seems to go against the stuff we've been talking about recently (see 'super and this' thread) where people have been saying that inherited classes are essentially wrapped into one. This is an example where the ancestor is being treated as an object in its own right. If inheritance worked the way people described in the previous thread, it ought not to be possible for a command to bypass the Child class and go straight to the Mother. The ancestor /is/ an object in its own right. Every object has a property __proto__ linking it to its prototype object. For every class, there is one single prototype (which in turn has its __proto__ set to its superclass' prototype, and so on, up the Prototype Chain to Object.prototype), and every instance of that class, as well as all prototype objects of its child classes, has it's __proto__ set to it. Example: class Foo { var name = "foo"; function Foo () {} function hello () { trace( "hello " + name ); } } class Bar extends Foo { function Bar () { super(); name = "bar"; } } What this gives you is nothing but a bunch of objects of two types, some of type "object", some of type "function" (which extends Object itself), and a single string (the second string in Bar's constructor only gets created whenever you create another instance): Foo is a function, the constructor of a class, as is Bar. They're normal functions, but for one property, Foo.prototype (resp. Bar.prototype). That's one of the object that just got created, the class' prototype. That prototype object has all the properties and methods that instances of the class shall inherit as properties, in this case, a function called "hello", which therefore would be Foo.prototype.hello, and one property of type string called "name". If you had an instance of Foo, myFoo, that would really only be an object. It wouldn't have a property "hello" or "name" itself, in fact, it would only have two properties, one for the prototype and one for the constructor. When you instantiate it with 'new Foo()', here's what happens: // instantiate the object: var myFoo = { __proto__: Foo.prototype, constructor: Foo }; // and call the constructor on it: myFoo.constructor.apply( myFoo ); Every object has those two properties, by the way. Even when you say {} what you really get is {__proto__: Object.prototype, constructor: Object}. (So, you can "instantiate" an object without calling its constructor -- if you did this with Bar, the resulting myBar would trace "hello foo" when you did myBar.hello().) Foo.prototype looks like this: Foo.prototype = { __proto__: Object.prototype, constructor: Foo, name: "foo", hello: function () { trace( "hello " + this.name ); } }; ...and Bar's prototype: Bar.prototype = { __proto__: Foo.prototype, // that's the inheritance! constructor: Bar, }; You can access myFoo.name, but it doesn't have a method "hello" or a property "name" itself. When you try to access "name" as myFoo.name, the virtual machine checks if your instance has that property. It doesn't, so it goes on to check the class' prototype object, which is where "name" is found -- myFoo.__proto__.name == Foo.prototype.name. Bar.prototype has a __proto__ property itself, set to Foo.prototype, and would inherit "name" the same way. Instances of Bar, however, would overwrite it in the constructor. That gives each single instance of Bar a property "name" set to "bar", while there is only one property "name" set to "foo", shared by all instances of Foo (and, oddly, by Bar.prototype). All of the following are true: Bar.prototype.__proto__ == Foo.prototype myBar.__proto__ == Bar.prototype myBar.__proto__.__proto__ == Foo.prototype myBar.__proto__.__proto__.__proto__ == Object.prototype So what's super, really? I have no idea. 'typeof super' traces "object", but somehow you can call it like a function. In the constructor, it behaves just as this.__proto__.__proto__.constructor would, and in methods, it behaves just as if it was this.__proto__.__proto__. It's not equal (as in '==') to either, though. It's a mystery, at least to me, maybe somebody can explain? Mark ___ Flashcoders@chattyfig.figleaf.com To change your subscription options or search the archive: http://chattyfig.figleaf.com/mailman/listinfo/flashcoders Brought to you by Fig Leaf Software Premier Authorized Adobe Consulting and Training http://www.figleaf.com http://training.figleaf.com
RE: [Flashcoders] Problem extending inherited function
> The way you had your code, the Child class will never receive > the killingFocus call. Add a Delegate within the Mother Class > to put the onKillFocus event into scope with Child... > > import mx.utils.Delegate; > > class Mother extends MovieClip { > public var txt:TextField; > > public function Mother() { > //this.onPress = killingFocus; > this.txt.onKillFocus = Delegate.create(this, killingFocus); > } > > public function killingFocus():Void { > trace("testFunc in mother"); > } > > } Hmm - this seems to go against the stuff we've been talking about recently (see 'super and this' thread) where people have been saying that inherited classes are essentially wrapped into one. This is an example where the ancestor is being treated as an object in its own right. If inheritance worked the way people described in the previous thread, it ought not to be possible for a command to bypass the Child class and go straight to the Mother. Danny ___ Flashcoders@chattyfig.figleaf.com To change your subscription options or search the archive: http://chattyfig.figleaf.com/mailman/listinfo/flashcoders Brought to you by Fig Leaf Software Premier Authorized Adobe Consulting and Training http://www.figleaf.com http://training.figleaf.com
RE: [Flashcoders] Problem extending inherited function
The way you had your code, the Child class will never receive the killingFocus call. Add a Delegate within the Mother Class to put the onKillFocus event into scope with Child... import mx.utils.Delegate; class Mother extends MovieClip { public var txt:TextField; public function Mother() { //this.onPress = killingFocus; this.txt.onKillFocus = Delegate.create(this, killingFocus); } public function killingFocus():Void { trace("testFunc in mother"); } } HTH - Andrew Rost -Original Message- From: Johan Nyberg [mailto:[EMAIL PROTECTED] Sent: Wednesday, March 21, 2007 3:10 AM To: flashcoders@chattyfig.figleaf.com Subject: [Flashcoders] Problem extending inherited function Hi, I have a problem extending an inherited function. I put all the files described here in a zip if you want to test it yourselves: http://www.webguidepartner.com/~johan/super-problem.zip I have this mother-class: class Mother extends MovieClip { public var txt:TextField; public function Mother() { this.onPress = killingFocus; //this.txt.onKillFocus = killingFocus; } public function killingFocus():Void { trace("testFunc in mother"); } } ...and this child-class that inherits from Mother: class Child extends Mother { public function Child() { super(); } public function killingFocus():Void { super.killingFocus(); trace("testFunc in child"); } } Now, I have a test.fla that contains a movie clip that is linked to Child. Everything works as expected, both lines of trace running on the onPress. But now: comment out the onPress-event in the constructor in Mother, and uncomment the second line: this.txt.onKillFocus = killingFocus; Now, there is a text field inside the movie clip. When this text field loses focus, you wold expect the code to run the same way, but no. The killingFocus-function in Mother is overwritten and only the trace in Child runs. I have some clue that the problem must have something to do with that it is the text field that triggers the event, and not the movie clip. But you would expect the super.killingFocus(); to work anyway, regardless of what calls the function?! Regards, /Johan -- Johan Nyberg Web Guide Partner Sergels Torg 12, 8 tr 111 57 Stockholm 070 - 407 83 00 ___ Flashcoders@chattyfig.figleaf.com To change your subscription options or search the archive: http://chattyfig.figleaf.com/mailman/listinfo/flashcoders Brought to you by Fig Leaf Software Premier Authorized Adobe Consulting and Training http://www.figleaf.com http://training.figleaf.com ___ Flashcoders@chattyfig.figleaf.com To change your subscription options or search the archive: http://chattyfig.figleaf.com/mailman/listinfo/flashcoders Brought to you by Fig Leaf Software Premier Authorized Adobe Consulting and Training http://www.figleaf.com http://training.figleaf.com
Re: [Flashcoders] Problem extending inherited function
This is a simple scope issue. The problem is caused exactly by that what you talked about. When assigning killingFocus to the textfield's event, use some kind of delegation (e.g. mx.util.Delegate): txt.onKillFocus = mx.utils.Delegate.create(this, killingFocus); (off: actually, "this" is not required inside AS2 classes) Attila JN> Hi, I have a problem extending an inherited function. I put all the JN> files described here in a zip if you want to test it yourselves: JN> http://www.webguidepartner.com/~johan/super-problem.zip JN> JN> I have this mother-class: JN> JN> JN> class Mother extends MovieClip { JN> public var txt:TextField; JN> JN> public function Mother() { JN> this.onPress = killingFocus; JN> //this.txt.onKillFocus = killingFocus; JN> } JN> JN> public function killingFocus():Void { JN> trace("testFunc in mother"); JN> } JN> JN> } JN> JN> JN> ...and this child-class that inherits from Mother: JN> JN> JN> class Child extends Mother { JN> public function Child() { JN> super(); JN> } JN> JN> public function killingFocus():Void { JN> super.killingFocus(); JN> trace("testFunc in child"); JN> } JN> } JN> JN> JN> Now, I have a test.fla that contains a movie clip that is linked to JN> Child. Everything works as expected, both lines of trace running on the JN> onPress. JN> JN> But now: comment out the onPress-event in the constructor in Mother, and JN> uncomment the second line: this.txt.onKillFocus = killingFocus; JN> JN> Now, there is a text field inside the movie clip. When this text field JN> loses focus, you wold expect the code to run the same way, but no. The JN> killingFocus-function in Mother is overwritten and only the trace in JN> Child runs. JN> JN> I have some clue that the problem must have something to do with that it JN> is the text field that triggers the event, and not the movie clip. But JN> you would expect the super.killingFocus(); to work anyway, regardless of JN> what calls the function?! ___ Flashcoders@chattyfig.figleaf.com To change your subscription options or search the archive: http://chattyfig.figleaf.com/mailman/listinfo/flashcoders Brought to you by Fig Leaf Software Premier Authorized Adobe Consulting and Training http://www.figleaf.com http://training.figleaf.com
Re: [Flashcoders] Problem extending inherited function
I have some clue that the problem must have something to do with that it is the text field that triggers the event, and not the movie clip. But you would expect the super.killingFocus(); to work anyway, regardless of what calls the function?! Yes, this is a scope issue -- it tries to call killingFocus on the TextField's super class. You have to delegate it, or just do: var f = function () { arguments.callee.self.killingFocus; }; f.self = this; this.txt.onKillFocus = f; HTH, Mark On 3/21/07, Johan Nyberg <[EMAIL PROTECTED]> wrote: Hi, I have a problem extending an inherited function. I put all the files described here in a zip if you want to test it yourselves: http://www.webguidepartner.com/~johan/super-problem.zip I have this mother-class: class Mother extends MovieClip { public var txt:TextField; public function Mother() { this.onPress = killingFocus; //this.txt.onKillFocus = killingFocus; } public function killingFocus():Void { trace("testFunc in mother"); } } ...and this child-class that inherits from Mother: class Child extends Mother { public function Child() { super(); } public function killingFocus():Void { super.killingFocus(); trace("testFunc in child"); } } Now, I have a test.fla that contains a movie clip that is linked to Child. Everything works as expected, both lines of trace running on the onPress. But now: comment out the onPress-event in the constructor in Mother, and uncomment the second line: this.txt.onKillFocus = killingFocus; Now, there is a text field inside the movie clip. When this text field loses focus, you wold expect the code to run the same way, but no. The killingFocus-function in Mother is overwritten and only the trace in Child runs. I have some clue that the problem must have something to do with that it is the text field that triggers the event, and not the movie clip. But you would expect the super.killingFocus(); to work anyway, regardless of what calls the function?! Regards, /Johan -- Johan Nyberg Web Guide Partner Sergels Torg 12, 8 tr 111 57 Stockholm 070 - 407 83 00 ___ Flashcoders@chattyfig.figleaf.com To change your subscription options or search the archive: http://chattyfig.figleaf.com/mailman/listinfo/flashcoders Brought to you by Fig Leaf Software Premier Authorized Adobe Consulting and Training http://www.figleaf.com http://training.figleaf.com ___ Flashcoders@chattyfig.figleaf.com To change your subscription options or search the archive: http://chattyfig.figleaf.com/mailman/listinfo/flashcoders Brought to you by Fig Leaf Software Premier Authorized Adobe Consulting and Training http://www.figleaf.com http://training.figleaf.com