PDA

View Full Version : overriding problem



dustinsmith08
January 8th, 2009, 06:16 PM
Ok so i finally ran into a problem I cant find a answer for.

I am making a class that loads/manages other class objects. In this master class I load the slave classes apply them to objects and then add the objects to the stage. Simple enough, the catch is that the loaded classes will be made by other people (who i don't trust :}) because of this I want to override some of the core classes like "addChild" so that when these independent classes try to add a new child I can use a use a custom class to add the child, run some checks, and do a few other things that need to be done.

I know about "override" the problem is that I dont know how to apply an override to all objects inside a parent - or - apply the custom classes when I create the object class.

basicaly i need the master class to take over the built in classes so I can manage the loaded "object classes" differently then the defualt classes do. And while I could do this from the loaded class I am not the one building those so I need override the built in classes externaly. Last I should mention that the slave classes come from the main timeline of loaded swf files

TheCanadian
January 8th, 2009, 09:01 PM
I don't entirely understand what exactly your having trouble with, but I hope this example helps.

package {
import flash.display.Sprite;
import flash.display.DisplayObject;
public class OverrideExample extends Sprite {
override public function addChild(child:DisplayObject):DisplayObject { //the method signature (arguments/type, return type, namespace (public, AS3, etc.) must match exactly
super.addChild(child); //you need to call the super classes method as well to use its existing implementation
trace("addChild method called"); //your extra code
return child;
}
}
}


var o:OverrideExample = new OverrideExample();
addChild(o);

var s:Sprite = new Sprite();
s.graphics.lineStyle(1);
s.graphics.drawRect(-10, -10, 20, 20);
o.addChild(s); //traces 'addChild method called' and adds the sprite as a child

dustinsmith08
January 8th, 2009, 11:22 PM
Thanks for the reply, thats what i need to do, BUT - i need to do it externally. If mutable inheritance were possible that would sort of solve my problem because really what I need to do is apply an object class (supplied by another person) and another class supplied by me (that helps the object interact with other objects) to the same MovieClip. I dont think I can do this but is it possible for me to extend the class supplied by another person(asume the exstact name is unknown because they are all loaded dynamicaly) externally.

in short, can i do something like this:

var newMovieClip:RandomClass = new RandomClass
var myControls:MyClass = new MyClass
myControls extends newMovieClip

Thanks

TheCanadian
January 9th, 2009, 01:01 AM
Composition

http://www.kirupa.com/forum/showthread.php?t=262393

dustinsmith08
January 9th, 2009, 04:01 AM
I spent some time looking at your other post and some other links on composition. If I understand composition, the slave class must still specify the other classes that it implements. Translated into my terms the slaveClass must ask that the masterClass be included. Is there a way for me to force the slaveClass to include the masterClass when they are both loaded by the rootClass. I really dont want to give the slaveClass the choice as to rather it implements the masterClass or not. I need to figure this out because I am not the one writing the slaveClasses and can't deppend on the authors to rememer to implement the masterClass.

TheCanadian
January 9th, 2009, 09:56 AM
If the methods of the slave class are known, you would create a composition of it in your master class and use wrapper functions to call its methods and any additional code you want.

If they aren't known, you could have your master class extend Proxy and redirect calls to unknown methods to your slave class.

Haha I don't know if this is helping at all.

dustinsmith08
January 9th, 2009, 04:27 PM
I think proxy/flash_proxy is what I need but im having a hard time understanding them or finding any information about them. If your willing to put up with a little more of my ignorance, could you throw me an example of how I would use proxy in my masterClass to override "addChild" in my slaveClass without specifying in my slaveClass that I am am overriding addChild, or that the masterClass extends it. (is this even something proxy can do?)

Thanks again for all your help

TheCanadian
January 9th, 2009, 08:52 PM
Well with Proxy, you'd have to call addChild from the master class instance and then redirect it to the slave class instance. I don't know if that's what you want.

If you were to extend the slave class, you could override addChild using the original code I posted.

Haha, I may be driving you in circles :run:

Krilnon
January 9th, 2009, 11:36 PM
I've been watching this thread since last night, but I wasn't crazy enough to try to reason with you until now.

First, to answer your more direct question:
is it possible for me to extend the class supplied by another person(asume the exstact name is unknown because they are all loaded dynamicaly) externally.

Not really. Why not? Because classes are "lame" and the class tree is basically fixed at compile time, with the exception that you can load in others from external SWFs/SWCs. However, that doesn't really help you to be able to subclass a user-generated class at runtime.

So, one option would be to load in the SWF with a URLLoader so that you could modify the raw ByteArray that represents the file and then load it as a SWF with Loader#loadBytes. However, that would be ridiculously complex because you'd have to know enough about the SWF file format to be able to insert your own classes in at runtime. It's still possible, though, so maybe you could be the first one to do it.

Another option would be to tell the people who are writing the classes that you're loading to use a more accessible (at runtime) form of OOP. Something like prototype-based OOP as described here: http://www.kirupa.com/developer/oop/AS1OOPPrototypes1.htm

I suggest that method because it would probably be the easiest for you to deal with as long as you can get these other programmers (that you don't trust) to cooperate.

Another method that would involve minimal cooperation on the part of the untrustworthies would be to have a class that the untrustworthy people would need to subclass in order to be able to run inside of your application. Even if they replaced the class that you gave them with another one, I think your class would still be the one to run as long as you used the right ApplicationDomain options. Something like this is described in one of the Flex manuals: http://livedocs.adobe.com/flex/201/html/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Book_Parts&file=18_Client_System_Environment_175_4.html

The application domain of module3.swf is a child of the current domain, and the child uses the parent's versions of all classes.

If you don't make these other users make their classes subclasses of something you can control, or you don't use a programming style that lets you make modifications at runtime, then what hope do you think you have of being able to control what their classes do? Take, for instance, a class from one of the untrusted people that is a direct subclass of Sprite. What could you possibly do there? You can't change the way that Sprite behaves, really, since it's a built-in class. You can't even use its prototype, even in ECMAScript compliance mode, to change the way that the built-in methods behave. As a result of that, there's no way of knowing whether some random private method in the user's custom class happens to call a Sprite method, right? Right. The only way to know for sure would be to do what I suggested first and look at the actual file in ByteArray form, and it would probably take a long time to figure out how to do that. It would be much easier to convince your users that if they want to have their stuff show up in your application, then they need to subclass one of your classes. That way, their attempts to trick would be fairly easy to avoid.

I'm sure you can find a way to make something like Proxy useful with composition (because if you subclass Proxy, you can't subclass a DisplayObject class with the same class, of course), but you'll still need a way to get between the user's class and the built-in classes.