Re: Scope in an interface?
Re: Scope in an interface?
- Subject: Re: Scope in an interface?
- From: Graham Reitz <email@hidden>
- Date: Sun, 25 May 2008 15:53:40 -0500
Outstanding! Thanks Jens!
Did you just type that up now? That seems like a lot of effort.
Much appreciated,
-graham
On May 25, 2008, at 2:41 AM, Jens Alfke wrote:
On 24 May '08, at 10:29 PM, Graham Reitz wrote:
Can I think of an @interface as something similar to a c++ class?
Yes. @interface is a class declaration, just as 'class' is in C++.
The variables declared in the "{...}" block are member variables,
and are protected by default. The object models of the two languages
are quite different, though, so classes and methods have differences
in behavior...
* The method implementations have to go inside a corresponding
@implementation block.
* No multiple inheritance, except of 'protocols', which you can
think of as special class declarations with no member variables and
only pure abstract virtual functions. (This is just like Java, which
in fact got it from Obj-C.)
* All methods are virtual.
* RTTI on steroids. Just about all information about any class can
be examined at runtime, and selectors are much more general than C++
method pointers. (It's actually C++ that's the odd language out;
most OOP languages have lots of reflection.)
* No abstract methods (except in the special case of protocols.) If
you want a method to be abstract you have to to do it by convention,
documenting the method as abstract and putting in an implementation
that does nothing or raises an exception.
* No such thing as private or protected methods. (Since the runtime
allows method calls to be generated at runtime using things like -
performSelector:, there's no practical way to enforce this.) The
usual equivalent is to use a 'category' to put the class's private
declarations into a separate header file that clients aren't
supposed to include.
* Class methods (the ones that start with "+" instead of "-") are
superficially like C++ static methods, but actually more powerful.
They're actually instance methods of the class itself (the class is
an object.) The most important difference is that they can be
overridden by subclasses just like instance methods.
* "Categories" allow classes to be extended after the fact. In
effect, anyone can add new methods to any existing class. (For
example, my app uses SHA-1 digests a lot, so I added a new -digest
method to NSData that computes its digest.)
* No stack-based (auto) objects. They have to be allocated on the
heap, as with "new".
* New objects are automatically zero-filled (as though operator new
were using calloc.)
* No notion of constructors or destructors built into the language.
There's merely a (very strong, universal) convention of using an -
init method for initialization; and the refcounting implementation
in NSObject makes sure to call -dealloc before freeing the object.
* No operator overloading. No polymorphic methods (overloading based
on different parameter types). No optional parameters or default
values.
* Calling any method on a NULL object pointer doesn't crash, and
doesn't call any code; instead, it's a no-op. This is actually
extremely useful and can be taken advantage of to make your code
much more concise by eliminating a lot of pointer checks.
* The built-in type "id" is similar to "void*" but specific to
object types. Any type of object can be assigned to or from "id"
without needing a type-cast. (It's like the kind of unchecked
dynamic typing used in languages like Python and Ruby.) Coming from C
++ or Java this may seem nasty, but it helps smooth out many of the
sharp edges caused by type-checking, especially in generic
collection classes, without the complexity of C++ templates or the
kind of type-inference found in functional languages.
* Method dispatch is more dynamic; it's based on the name of the
method (the selector) not a vtable offset. This means that even if
you don't know the class of an object at compile time, you can still
call methods on it. For example, given a declaration "id foo", you
can call [foo doSomething] and it will successfully call a method
named doSomething, if foo has a base class that implements it, no
matter what the class hierarchy looks like.
* No "fragile base class problem" for methods: you can add methods
to a base class without breaking binary compatibility of subclasses.
(The 32-bit runtime has fragile instance variables, though, but the
new 64-bit one doesn't.)
Hope this helps :)
—Jens
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden