We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
Page Index Toggle Pages: 1
Which class? (Read 1300 times)
Which class?
Aug 25th, 2009, 11:01am
 
I have a class tree, with one base class and several subclasses. Some of them need to check the others to see if they are of a particular kind. I can do that by instantiating an object of the desired class and use obj.getClass(), but that is kind of roundabout and also leads to recursion and stack overflow.

I would like to do something like: String className = MyClass.getName(); but Processing claims "The function getName() does not exist." Why does it say that?
Re: Which class?
Reply #1 - Aug 25th, 2009, 12:05pm
 
If you place the following methods in the base class then you can get the class name for any object and be able to compare any object with another object (assuming that all objects are created from the base class or it's children).

NOTE: in the second fuction replace BaseClass with the name of your base class)


Code:

public class BaseClass {

/**
* Returns the name of the class for any object of this
* class or sub class.
* @return class name (without package name if any)
*/
public String getMyName(){
return this.getClass().getSimpleName();
}

/**
* Compares this object with another object from the same
* class hierarchy.
* @param obj
* @return true if same class
*/
public boolean isSameClassAs(BaseClass obj){
return this.getMyName().equals(obj.getMyName());
}

}
Re: Which class?
Reply #2 - Aug 25th, 2009, 12:18pm
 
Quark: Thanks for the reply – but that's not quite what I wanted (and quite doable by using obj.getName(), which works fine on objects).

What I want to do is find/store the name of a class, without instantiating an object.
Re: Which class?
Reply #3 - Aug 25th, 2009, 12:42pm
 
Don't you already know the name of your class?  I mean, you named it...?

String className = "whateverYourClassNameIs";

pardon my density?
Re: Which class?
Reply #4 - Aug 25th, 2009, 1:10pm
 
Ha ha, yes, I can see why you'd think that!

I guess I'm striving for more elegance than can be found in Processing.

Example of what I'm looking for, in pseudo-pseudocode (i.e., the way I would like it to work):
Code:
class Organism {
 Class food;
 Organism() {}
}
class Plant extends Organism {
 Plant() {}
}
class Animal extends Organism {
 Animal() {}
}
class Herbivore extends Animal {
 Herbivore() { food = Plant.getClass(); }
 boolean likesToEat(Organism o) {
   return (o.getClass()==food);
 }
}
class Carnivore extends Animal {
 Carnivore() { food = Herbivore.getClass(); }
 boolean likesToEat(Organism o) {
   return (o.getClass()==food);
 }
}

Re: Which class?
Reply #5 - Aug 25th, 2009, 2:05pm
 
well...if you're passing a given organism through "likestoeat( Organism o)" then it should exist as a checkable object, no?

Of course if getClass() returns a String then you'd use if StringA.equals(StringB) rather than == ...

Would it be too inelegant to say:

Quote:
class Organism {
  String food, type;
  Organism() {}
}
class Plant extends Organism {
  Plant() { type = "plant"; }
}
class Animal extends Organism {
  Animal() { type = "animal"; }
}
class Herbivore extends Animal {
  Herbivore() { food = "plant"; }
  boolean likesToEat(Organism o) { return (o.type.equals(food)); }
}
class Carnivore extends Animal {
  Carnivore() { food = "animal"; }
  boolean likesToEat(Organism o) { return (o.type.equals(food)); }
}
Re: Which class?
Reply #6 - Aug 26th, 2009, 5:16am
 
Quote:
Would it be too inelegant to say:

It just feels redundant to add strings describing the type of class when the classes already have a type ...

But I guess I don't have much choice. Apparently there are limits to what you can do with static classes, variables and functions. I was almost there, but then a call to a non-static function from a static class isn't permitted, so I had to go with your suggestion and use strings for type identification.

Thanks for your help!
Re: Which class?
Reply #7 - Aug 26th, 2009, 5:35am
 
Have you looked at some programmers' code?  Cheesy Most would benefit from having something as simple as a String which identifies the class name. I think that's quite elegant to have something so readable and readily identifiable!
Smiley
Re: Which class?
Reply #8 - Aug 26th, 2009, 7:18am
 
travholt wrote on Aug 25th, 2009, 1:10pm:
Example of what I'm looking for, in pseudo-pseudocode (i.e., the way I would like it to work)

Here is how to make it work: Code:
void setup()
{
println("Creating world");
Plant grass = new Plant(); println();
Plant daisy = new Flower(); println();
Animal cow = new Herbivore(); println();
Animal lion = new Carnivore(); println();
Animal pig = new Omnivore(); println();

println();
println(lion.likesToEat(cow));
println(lion.likesToEat(pig));
println(lion.likesToEat(grass));
println(lion.likesToEat(daisy));
println();
println(cow.likesToEat(lion));
println(cow.likesToEat(pig));
println(cow.likesToEat(grass));
println(cow.likesToEat(daisy));
println();
println(pig.likesToEat(lion));
println(pig.likesToEat(cow));
println(pig.likesToEat(grass));
println(pig.likesToEat(daisy));
println(pig.likesToEat(pig));

println(pig.isLiving);
}

interface Eater {
boolean likesToEat(Organism o);
}
abstract class Organism {
boolean isLiving;
Organism() { isLiving = true; print(this.getClass().getSimpleName() + " > Organism"); }
}
class Plant extends Organism {
Plant() { print("-Plant"); }
}
class Flower extends Plant {
Flower() { print("-Flower"); }
}
abstract class Animal extends Organism implements Eater {
Animal() { print("-Animal"); }
}
class Herbivore extends Animal {
Herbivore() { print("-Herbivore"); }
boolean likesToEat(Organism o) {
return o instanceof Plant;
}
}
class Carnivore extends Animal {
Carnivore() { print("-Carnivore"); }
boolean likesToEat(Organism o) {
return o instanceof Animal;
}
}
class Omnivore extends Animal {
Omnivore() { print("-Omnivore"); }
boolean likesToEat(Organism o) {
return o instanceof Animal || o instanceof Plant;
}
}

The interface defines a common trait, the fact the organism can eat. Any class implementing this interface can eat. But you have to define it. That's where the information on what can eat what is stored, not in a field.
I made some classes abstract because they shouldn't be instanced (too generic). Plant should be abstract, but I took a shortcut here...

[EDIT] Added constructor trace to better see the cascading default constructor mechanism.
Re: Which class?
Reply #9 - Aug 27th, 2009, 3:25am
 
travholt said:
Quote:
I guess I'm striving for more elegance than can be found in Processing.


Unfortunately the elegance you seek in not available in the Java programming language either.  Sad

You have to live with the fact that getClass() is not a static method and if it was Organism.getClass() makes no sense because you already know the class i.e. Organism. Also a base class cannot know about classes that inherit from it.

The code provided by PhiLho is a very elegant solution to your problem.
Smiley



Page Index Toggle Pages: 1