|
metadata
It is possible to take an object `objectA` of type `subclassA` which is a subclass of `classA` and check if `objectA` is of either of these types using the statement: `objectX is classX` (AS3 will check as many superclasses as necessary).
Say you have several user-defined classes, `classB`, `classC`, … and `classZ`. `classB` is a subclass of `classC`, `classC` is a subclass of `classD` and so on, with `classZ` being the most basic class.
Like the first example, how would I check if `classB` is a(n indirect) subclass of `classZ`?
[http://www.kongregate.com/forums/4-game-programming/topics/202566-as3-comparing-classes?page=1#posts-4380559](http://www.kongregate.com/forums/4-game-programming/topics/202566-as3-comparing-classes?page=1#posts-4380559)
|
|
|
metadata
take this scenario objectA inherits from classA. in classA I would have a variable for identification say id=1; or idStr = “ClassA”; then when I need to check if objectA is from classA all I have to do is if(objectA.id == 1) trace(“classA”); or if(objectA.idStr == “ClassA”) trace(“ClassA”);
make sure this variable is const though.
|
|
|
metadata
I’m wanting to make the comparison without instantiating anything.
|
|
|
metadata
Try something like:
`
if(ClassA.prototype instanceof ClassB)
`
And ignore the instanceof is deprecated warning.
|
|
|
metadata
> *Originally posted by **[Dealmaster13](/forums/4/topics/202566?page=1#posts-4380372):***
>
> I’m wanting to make the comparison without instantiating anything.
Thats a bit strange. what are you trying to do?
Also bob I dont think that will work.
|
|
|
metadata
> *Originally posted by **[BobTheCoolGuy](/forums/4/topics/202566?page=1#posts-4380420):***
>
> Try something like:
>
> `
> if(ClassA.prototype instanceof ClassB)
> `
>
> And ignore the instanceof is deprecated warning.
~~[`instanceof`](http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7f8a.html) uses objects (instances), which is not what I’m after.~~
> *Originally posted by **[simplegoogly](/forums/4/topics/202566?page=1#posts-4380463):***
> > *Originally posted by **[Dealmaster13](/forums/4/topics/202566?page=1#posts-4380372):***
> >
> > I’m wanting to make the comparison without instantiating anything.
>
> Thats a bit strange. what are you trying to do?
>
> Also bob I dont think that will work.
I have, say, a specific weapon/turret class, `MachineGun`. The hierarchy works as so:
`MachineGun` —\> `OffensiveTurret` —\> `Turret`
I want to know if `MachineGun` is a `Turret` and not a `Building` or an `Animal` without using a user-defined lookup table for subclasses of `Turret`.
|
|
|
metadata
Yeah, what are you trying to do. This is one of those things where it’s like doing:
`if(true) {
}`
Because you, the programmer, can check to see if ClassA extends/implements ClassB, it’s _not like it’s going to change._
|
|
|
metadata
> *Originally posted by **[simplegoogly](/forums/4/topics/202566?page=1#posts-4380463):***
> > *Originally posted by **[Dealmaster13](/forums/4/topics/202566?page=1#posts-4380372):***
> >
> > I’m wanting to make the comparison without instantiating anything.
>
> Thats a bit strange. what are you trying to do?
>
> Also bob I dont think that will work.> *Originally posted by **[Draco18s](/forums/4/topics/202566?page=1#posts-4380562):***
>
> Yeah, what are you trying to do. This is one of those things where it’s like doing:
>
> `if(true) {
> }`
>
> Because you, the programmer, can check to see if ClassA extends/implements ClassB, it’s _not like it’s going to change._
What Draco said is correct. However, my example will still do what he is asking. Normally though, it is for when you’re passing around a class as an object, and you don’t know its type. For example, say you have a function:
`
function createEnemy(Type:Class):void
{
if(Type.prototype instanceof Enemy)
var enemy:Enemy = new Type();
}
`
You can use what I posted to ensure that a class is the correct type.
Perhaps that will clear it up.
|
|
|
metadata
Bob OP asked for n number of subclasses? will it still work?
Also instead of instanceOf one can use getQualifiedClassName so your example can become
`
function createEnemy(Type:Class):void
{
if(getQualifiedClassName(Type.prototype) == "Enemy")
var enemy:Enemy = new Type();
}
`
Also there is getQualifiedSuperclassName which returns the base class but not sure if it will work with n number of subclasses.
`
if(getQualifiedSuperclassName(Type) == "Enemy")
{
}
`
|
|
|
metadata
Yes, that is correct, Draco, however I’m not going to store what each of my classes extends with the hope that there is a more elegant, ‘behind the scenes’, solution available.
Your code does indeed work, Bob. I apologise for not trying it out earlier. `instanceof` is of course depreciated however, so is there not an alternative method? It seems strange that while `is` is supposed to mimic `instanceof` ’s function that it should not behave in the same way.
|
|
|
metadata
Maybe I am misunderstanding what you want to do but it sounds like “is” is what you are after to me. Code like “objectX is classX” would return true if any part of objectX’s class hierachy contained classX.
|
|
|
metadata
Comparing classes; not objects with classes.
|
|
|
metadata
Why do you have to compare the classes? What’s stopping you from creating the object before you check it?
|
|
|
metadata
> *Originally posted by **[BIGMANONCAMPS](/forums/4/topics/202566?page=1#posts-4381858):***
>
> Why do you have to compare the classes? What’s stopping you from creating the object before you check it?
Plenty of reasons not too – why would he want to allocate memory and spend processing time creating a `HugeComplexAIReaoningModule` just to check if it is a subclass of something?
|
|
|
metadata
Creating the object will change variables and create event listeners.
I think it’s safe to say that there is no up to date built-in solution.
|
|
|
metadata
How about something like:
`
private var _turret:Turret;
try
{
_turret:Turret = new Class();
}
catch (e:Error)
{
trace("Not a turret");
_turret = new DefaultTurretClass();
}
`
I’m still struggling to think why you need to do this at run time. It would be much easier if you just told us what you are trying to do.
|
|
|
metadata
See [this post](http://www.kongregate.com/forums/4-game-programming/topics/202566-as3-comparing-classes#posts-4380559) if you’re interested.
|
|
|
metadata
I’ve done this before, all you have to do is use to `is` operator. Since `classA` extends `classB`, and `classB` extends `classC`, all the way to `classZ`, any object of `classB` is also considered a member of every ancestor class all the way through to `classZ`. For example, this code should work:
`var object:classB;`
`trace(object is classZ); //true`
|
|
|
metadata
You probably didn’t read the whole topic, but also unknowingly suggested a very nice thought, but unfortunately it doesn’t work without instantiation.
|
|
|
metadata
> *Originally posted by **[Ignitus1](/forums/4/topics/202566?page=1#posts-4393346):***
>
> I’ve done this before, all you have to do is use to `is` operator. Since `classA` extends `classB`, and `classB` extends `classC`, all the way to `classZ`, any object of `classB` is also considered a member of every ancestor class all the way through to `classZ`. For example, this code should work:
>
> `var object:classB;`
>
> `trace(object is classZ); //true`
That would be an interesting idea if you could do that, but since you haven’t instantiated object, it will fail, since object will be null.
|
|
|
metadata
Yeah… what he’s asking for is a `willBe`, not an `is`.
|
|
|
metadata
I’m not sure if this will help or not…
And I’m not sure why exactly simplegoogly’s methods didn’t work for what you need but here’s another similar to his suggestions.
`
private function classcheck(type:Class) {
if(getDefinitionByName(getQualifiedClassName(type)) == EnemyClass){
//stuff
}
}
`
The only difference is i’m not using prototype and I’m using getDefinitionByName.
I also checked it in the middle of my enemy spawner and the trace ran fine.
`
private var monsterCreationTimer:Timer;
private var m_class:Class;
private var monster:MovieClip:
private var m_type:Array; //array of strings
private function monsterCreation(e:TimerEvent){
//blah blah blah unimportant stuff and if checks
m_class = getDefinitionByName(m_type[index]) as Class;
if(getDefintionByName(m_type[index]) == Monster_A){
trace("This is silly.");
}
monster = new m_class();
//add relevant listeners and other unimportant stuff
}
`
|
|
|
metadata
Based on simplegoogly and NicheGamer’s suggestions:
`
/**
* Returns whether type is superClass or is a subclass of superClass.
*/
public static function subclassOf(type:Class, superClass:Class):Boolean {
try {
for(var c:Class = type; c != Object; c = getDefinitionByName(getQualifiedSuperclassName(c))) {
if(c == superClass) {
return true;
}
}
} catch(e:Error) {}
return false;
}
`
Untested, but it should work.
|
|
|
metadata
Interesting idea player\_03; I think I might just implement that. Thanks!
|
|
|
metadata
> *Originally posted by **[player\_03](/forums/4/topics/202566#posts-4396274):***
>
> Untested, but it should work.
`ClassZ -> ClassC -> ClassB`
ClassC will return true. ClassB will return false. a ClassB instance will return true for `is ClassZ`. superclass goes one level up, just one.
describetype is how you could easily check all, but is completely pointless.
just use a container object (you can even have just one and just reuse it). or store all of the classes in an Array/Vector and pass an index.
either way, you’ll be checking against a set of numbers (not strings! they are unnecessarily slow. if you need a name, make them `static const int`s and use that name) to perform a certain actions and instantiate a class
|