3

I am not sure if I am missing something here. I would like to compare two classes that uses the same interface. Is this possible? I understand that the is operator compares classes, but is there any similar function when you use interfaces?

// works
var effect1 : CrazyEffect = new CrazyEffect();
var effect2 : SaneEffect = new SaneEffect();

trace(effect1 is effect2) // false

// does not work
var effect1 : ISoundEffect = new CrazyEffect();
var effect2 : ISoundEffect = new SaneEffect();

trace(effect1 is effect2)

1067: Implicit coercion of a value of type ISoundEffect to an unrelated type Class.

Mattias
  • 3,907
  • 4
  • 28
  • 50

2 Answers2

4

Note the differences between concepts of a class and of an object. The former is a data type whereas the latter is a runtime instance of it, a variable. is operator can not compare one variable to another.

According to language reference

is Operator

Evaluates whether an object is compatible with a specific data type, class, or interface. Use the is operator instead of the instanceof operator for type comparisons. You can also use the is operator to check whether an object implements an interface.

In other words, compiler expects the first operand to be a variable whereas the second operand should be a type identifier.

var sample:String = "Object is an instance of a class.";
     ^^^    ^^^
variable    type identifier  

However effect2 is not a type identifier but a variable. Hence the error message.

Unfortunately there is no generic operator to test for interface commonality. The only alternative is:

trace((s is ISoundEffect) && (t is ISoundEffect));

Update

Checking whether objects are instances of a same class can be done by comparing class names:

if (getQualifiedClassName(effect1) == getQualifiedClassName(effect2)) {
   // true
}

For in depth discussion see Get the class used to create an object instance in AS3

Saul
  • 17,973
  • 8
  • 64
  • 88
  • Ok. Thanks. I think I will add a getter to the interface to be able to use `(effect1.type == effect2.type)` instead. – Mattias Oct 07 '11 at 10:20
  • I looked at your code again. It it not doing what I intend to do. I already know that both classes are using the interface. I want to see if effect1 and effect2 is the same class. – Mattias Oct 07 '11 at 16:49
  • 1
    Then you should look at `getQualifiedClassName()` and `getQualifiedSuperClassName()` I guess. – frankhermes Oct 07 '11 at 17:59
  • @Mattias - In that case what frankhermes suggests is correct. See update. – Saul Oct 07 '11 at 18:33
1

Even though it will work with getQualifiedClassName, there's a better method to check whether two objects are instances of the same class:

a['constructor'] === b['constructor']

getQualifiedClassName is very slow and CPU intensive. Since the above code just compares property values it is lightning fast. And yes, constructor IS a property of every object, however FB will complain if you try to access it using dot-notation, that's why I use dynamic property access.

Creynders
  • 4,573
  • 20
  • 21
  • Interesting! I added a getter (`String`) to compare the types instead. Works fine. But I did not know that you could access `constructor`. +1 – Mattias Oct 09 '11 at 07:39
  • Ahh, ECMAScript. Another interesting fact, every data type in AS3 actually has a `prototype` property too. You can add properties/methods to any class or even override the base `Object.toString` implementation if you want, and it'll affect all existing sub-classes, but it's highly un-recommended. – Peter Oct 09 '11 at 07:56
  • @Peter: Ssssssh.... That's something that should stay secret, we REALLY don't want to go back to the ol' days of AS2 monkey patching :) – Creynders Oct 09 '11 at 08:06