mazz0
mazz0

Reputation: 715

Am I doing this the Objective-C way? (no static class variables)

OK, imagine I have a Zoo, and I only want it to contain animals of a certain colour. I have a Zoo object, which has a colour property (a char, in this example, could just as well be an object of some sort). I also have an Animal class, which I never instantiate (I still think of it as being abstract, I'm java) because I extend it with animal types.

I want to check whether I can add a particular animal type to my zoo. I don't like the idea of making colour a property of Animal and having to instantiate each Animal before I can check whether I can have one. Seems to me I want colour t be a class variable of Animal rather than an instance variable, at least that's how I'd have done it in Java, but I get that the style is quite different.

My solution was:

in ZooController:

if([zoo canAddAnimalOfType:[Elephant class]])
{
     [zoo addAnimal:([Elephant animal])];
}

and in Zoo:

@property char colour;

- (BOOL)canAddAnimalOfType:(Class)animalType
{
    if([animalType colour] == colour)
    {
        return YES;
    }
    else
    {
        return NO;
    }
}

and here was my solution to lack of class variables in Animal (which Elephant extends):

+(char)colour
{
    return 'n';
}

So in effect I'm using a class method to encapsulate a class variable, which seems kinda messy to me. My question is, is this the Objective C way? If not, what would be?

Thanks

Upvotes: 1

Views: 173

Answers (2)

rob mayoff
rob mayoff

Reputation: 385680

Yes, this is the Objective-C way (although the example scenario is questionable). When you have a value that is guaranteed to be the same for all instances of a class, but may change depending on subclass, use a class method to return the value. (This is not the only use of class methods.)

Here are some examples from Apple's frameworks. There are others.

Upvotes: 3

Benjamin Mayo
Benjamin Mayo

Reputation: 6679

Personally, that looks wrong to me. For this scenario, class methods feel ugly. I would instantiate the Elephant object and then test if that instance could go in the zoo. Why? Because you might want Elephants to have more than just one colour. Rather than subclassing for each different variant, you can simply set @property's on each instance and pass the instance to the zoo to test.

If initialising an Animal object is very expensive, you could use a slightly-different pattern. Create a lightweight class called an AnimalDescriptor, which you can instantiate to describe an animal's properties rather than the actual object. If the test passes, then use the descriptor to create a full object.

Upvotes: 1

Related Questions