That works fine (notice the type cast to keep static typing intact), although I can't imagine why I'd ever need to do something like that. If I want a base Enemy class and have enemy subclasses that have their own specialized functions, I'd either:

a) Have separate arrays for each enemy type to keep things structured and organized (then I'd already know exactly which functions I'd be allowed to call)
b) Just have each subclass override a generic update() function.

Although, being a C++ programmer, I'm just conditioned to think that way. I like how the language imposes a sense of structure on me, to force me to stay organized. (also completely opinion)

I've used Qt, which hacks reflection on top of C++. It's vile. If you have to go to that amount of trouble to add a feature which is a central part of any sane language, you're using the wrong language.

OneSadCookie Wrote:Yes, of course that works fine. What doesn't work fine is this:

Code:

<snip>

Again, I can't even begin to imagine why I'd ever design a program like that. That's just horrendous design in my opinion. I'd use separate arrays for each class type to keep things organized, or just have each thing use a specialized update() function (which I personally don't do, but I've seen some people use that).

Cocoa uses the ability to send a random message to a random object extensively -- every delegate object, for a start. The fact that a message is a thing in and of itself is also important (eg. for -performSelectorOnMainThread:withObject:waitUntilDone. These things are crucial to the ease-of-use of Cocoa, and one of the major reasons why Java/Swing or C++/Qt (despite its hacked "equivalents") are nowhere near as nice to use.

Bottom line is, if you don't think this behavior is useful, you haven't done enough object-oriented design work

It's basically rooted in the confusion between "inheritance of interface" and "inheritance of implementation" that so many languages (C++, Java, etc) have. Languages like Python, Ruby, and to a lesser extent ObjC, that don't make a big fuss about formal interface, handle the issues of building a flexible object-oriented design much better.

OneSadCookie Wrote:Animals don't bark, so having every animal implement a bark() method just so I can call it on Seals and Dogs is a very bad idea... just think of how many methods that do nothing in 90% of cases will be on the Aninmal class!

Well, the point of inheritance is to put the most common "stuff" at the top level, no *everything*, although nothing prevents you from putting empty stubs for methods if you want.

Now, if I were to put a bark() method in my Animal class, then it would be because I expect a good number of them to implement this method, otherwise what would be the point of a function taking an Animal instance and asking it to bark? If I actually want this to be useful, then I'll probably care about whether an animal can or can't bark, and so my function would take an appropriate subclass of Animal, say AnimalThatBarks, from which both Dog & Seal would inherit the bark() method.

Obj-C allows a lot of flexibility in comparison, but at the cost of hard to catch runtime errors, as early versions of both Project Builder and Xcode showed.

PowerMacX Wrote:If I actually want this to be useful, then I'll probably care about whether an animal can or can't bark, and so my function would take an appropriate subclass of Animal, say AnimalThatBarks, from which both Dog & Seal would inherit the bark() method.

Which is fine as long as you are responsible for all the code...

Early versions of Java suffered from this. A good number of classes implemented a "boolean compareTo(Object other)" method, but there was no base class or interface that declared this method. That meant that whilst it would make sense to write a function like "static void sort(ObjectThatImplementsCompareTo[] array)", the only way you could actually do that was to make your sort method take an Object[] and call compareTo via reflection. Ick. (Later versions of Java added a Comparable interface and retroactively made all classes that had a compareTo method implement Comparable).

You may also hit an issue like this when dealing with third-party code -- imagine you're writing an audio app, and purchase an MP3SoundPlayer class from vendor A, and an AACSoundPlayer class from vendor B. Both have a play() method, but since they don't share a common ancestor which does, you have to wrap both classes up before using them, if you want to treat them uniformly.

Curious if anyone knows:
Is there an easy way to do abstract classes and methods (ala Java) in Objective-C? I know I can make hard/soft protocols but I'm more interested in the ability to implement most of a class and then leave the details to subclasses (and also barring instantiation).

The ususal way to implement an abstract method in ObjC is to declare it normally, and have it raise an exception when called (there is a particular kind of exception that's standardly used, but the exact name slips my mind... NoSuchMethodError maybe?).

Obviously, that's not really the same as Java or C++, where the compiler will force you to implement all the abstract methods, but this again comes back to ObjC's general unconcernedness with formal interfaces.

PowerMacX Wrote:Obj-C allows a lot of flexibility in comparison, but at the cost of hard to catch runtime errors, as early versions of both Project Builder and Xcode showed.

`hard to catch runtime errors' is a partly true. I say that because in the experience that I've had with Obj-C/Cocoa for the last few years, nine out of every ten (maybe even ten out of ten) of those errors were simple, silly mistakes on my part (calling an object that I released, etc.). Over time I have learned not to make those mistakes and now it is *very* rare to create a runtime problem that I can't track down in a few minutes.

Also, don't forget that with Obj-C you can query the actual names of the classes being called, pre-flight them to make sure they even have that method, and so on. Obj-C is not only flexible but informative when necessary.

Over-generalizing, but: With something like C/C++ there are mostly barriers to overcome. Something might not work in a large API and it could take a long time to figure it out. Whereas with Obj-C/Cocoa I might accidentally do something that actually works and I have to sometimes sit back and try to figure out how it figured out what I wasn't trying to do. Instead of breaking the flow of the program it might just skip past it and spam the log instead. Really cool stuff!