views:

59

answers:

3

Is there any non-hacky way to determine wether a class' superclass implements a particular interface?

For example, assume I've got:

class A extends EventDispatcher implements StuffHolder {
    protected function get myStuff():Stuff { ... };

    public function getStuff():Array {
        if (super is StuffHolder) // <<< this doesn't work
            return super['getStuff']().concat([myStuf]);
        return [myStuff];
}

class B extends A {
    override protected function get myStuff():Stuff { ... };
}

How could I perform that super is StuffHolder test in a way that, well, works? In this case, it always returns true.

+1  A: 

In this case you might have to define StuffHolder (and have it extend EventDispatcher) as a class and have getStuff as a public/protected function. You could then overload the getStuff function in class A, but not in class B.

package {
 public class StuffHolder extends EventDispatcher {
  function StuffHolder() {

  }
  protected function getStuff():Array{
   return ["Default"];
  }
 }
}
package {
 public class A extends StuffHolder {
  function A {
   super();
  }
  protected override function getStuff():Array {
   return ["A"];
  }
 }
}
package {
 public class B extends StuffHolder {
  function B {
   super();
  }
 }
}
Sandro
The problem here is that you can't do multiple inheritance with AS3, which I think would help in your case. This post may also help you. http://www.darronschall.com/weblog/2006/10/multiple-inheritance-in-actionscript-3.cfm good luck!
Sandro
Yup, that's the problem. In my case, the `getStuff` function is actually a mixin that's being implemented via an `include "..."`, so I don't want to change the superclasses of the stuff I'm extending.
David Wolever
+1  A: 

I don't have the full picture to figure out why you'd need that kind of (weird and possibly broken) inheritance, but could you rephrase it to if (this is actually an A instance)?

If so, you could go with...

import flash.utils.getQualifiedClassName;

if (getQualifiedClassName(this) == 'A')

The thing is, the is operator should be used on object instances. And it works all the way up to object -- I mean, A is B is true for every A ancestor or interface implementation.

I think you could come up with a better structure for your classes, though. This isn't that pretty.

MrKishi
As I mentioned on Sandro's comment, my `getStuff` function is actually a mixin that's being `include "..."`'d, so it doesn't even know what class it's on. The only thing it knows is that the class that it's being applied to has implemented the `StuffHolder` interface.
David Wolever
Omg.. It's getting even uglier.Alright. So.. Is "if (super.foo != null) super.foo()" enough?Or do you need to know if it _really_ implements StuffHolder?If so... Reflection. "describeType(getDefinitionByName(getQualifiedSuperclassName(this)))" will return the superclass (EventDispatcher, in the A class, for example) XML description. It'll have a "<factory />" tag with a list of it's implemented interfaces...
MrKishi
A: 

I could do something involving introspection, getting the current class, finding its parent class, then checking to see if that implements the StuffHolder interface… But that seems pretty ugly :(

David Wolever