Object Antics
As with all Object-Oriented languages, Objective-C allows for some pretty handy trickery when it comes to objects, inheritance, and extensions. The terms used are fairly exclusive, but most of them have parallels.
In Cocoa Objects I briefly went over how to do basic inheritance. It is done by adding : InheritedObject
on the @interface
line, like this:
@interface myObject: NSObject
Objective-C does not allow multiple-inheritance. This means each object can only inherit from one object, and has only one
super
class, which we'll get into later.Related to inheritance is an idea Objective-C refers to as
Protocols
. A protocol is comparable to a virtual class in C++, in that it defines what methods need to exist, but doesn't define how they work.A protocol is defined very simply, as follows:
@protocol myProtocol
-(void) aMethod;
-(void) anotherMethod;
@end
For an object to adhere to this protocol, it must implement two methods, called
aMethod
and anotherMethod
.To indicate that an object adheres to a protocol, we use code like this:
@interface myClass: <myProtocol>
The stuff between the less-than and greater-than signs defines the protocol or protocols. If there are multiple protocols an object adheres to, they all appear between the brackets, in a comma-separated list, like this:
@interface myClass: <myProtocol, anotherProtocol>
Objects are meant to be dynamic in Objective-C. As such,
NSObject
provides a number of handy methods to help figure out what class an object inherits and what methods it uses.#import <Foundation/Foundation.h>
@interface basicClass: NSObject
{
int basicInt;
}
@end
@interface mediumClass: basicClass
{
int mediumInt;
}
@end
@interface complexClass: mediumClass
{
int complexInt;
}
@end
@implementation basicClass
@end
@implementation mediumClass
@end
@implementation complexClass
@end
int main()
{
basicClass *bcObj = [[basicClass alloc] init];
mediumClass *mdObj = [[mediumClass alloc] init];
complexClass *cxObj = [[complexClass alloc] init];
if( [cxObj isKindOfClass: [mediumClass class]] == YES )
printf("cxObj is a kind of mediumClass\n");
else
printf("cxObj is not a kind of mediumClass\n");
if( [cxObj isKindOfClass: [basicClass class]] == YES )
printf("cxObj is a kind of basicClass\n");
else
printf("cxObj is note a kind of basicClass\n");
if( [bcObj isKindOfClass: [mediumClass class]] == YES )
printf("bcObj is a kind of mediumClass\n");
else
printf("bcObj is not a kind of mediumClass\n");
return 0;
}
As you can probably expect from this example, the output is this:
cxObj is a kind of mediumClass
cxObj is a kind of basicClass
bcObj is not a kind of mediumClass
We can use the
isKindOfClass
method to see if an object we get is of a particular kind. We can use the class
method to get an object's class.A related method is
isMemberOfClass
, which is used in exactly the same way as isKindOfClass
. While isKindOfClass
will return YES if any parent object is the specified class, isMemberOfClass
will only return YES if the object in question's immediate parent (the super
class) is the specified class. If we replace all all occurrences of isKindOfClass
with isMemberOfClass
in the example above, the output becomes:cxObj is not a member of mediumClass
cxObj is note a member of basicClass
bcObj is not a member of mediumClass
Notice how
complexClass
is not a member of basicClass
because basicClass
is a grandparent object, not an immediate parent of complexClass
.There are a few other methods related to object methods, but they use
selectors
so I'll address those in a future entry. There are also methods we can use to determine if an object conforms to a given protocol. This will also be addressed later.Up to this point, we've only dealt with
@private
for member variables, not methods. In fact, if you got adventurous and tried to mark some methods as private, you probably ran into some problems. This is because Objective-C has no syntax to create private member functions. The way around this is by using Categories. Categories are used to extend the functionality of a class by adding new methods. Simple usage looks like this:#import
@interface basicClass: NSObject
{
int basicInt;
}
@end
@implementation basicClass
@end
@interface basicClass (Extension)
-(void)extendedMethod;
@end
@implementation basicClass (Extension)
-(void)extendedMethod
{
printf("This method is in a category called \"Extension\"\n");
}
@end
int main()
{
basicClass *bcObj = [[basicClass alloc] init];
[bcObj extendedMethod];
return 0;
}
The
(Extension)
part defines the Category, which is called "Extension" in this case. The name can be pretty much anything though. However, each category name must be unique. Also, categories cannot add member variables, only methods.Predictably, the output of the Category example above is:
This method is in a category called "Extension"
So, to create private member functions, all you need to do is add a Private category in the object's
.m
source file instead of the .h
. This keeps the method inaccessible to callers outside of that .m
file.One last object trick available in Objective-C is the ability for a class to pose as its super class. This feature is aptly named "Posing." To have a class pose as another class, we use the
poseAsClass
method.#import <Foundation/Foundation.h>
@interface basicClass: NSObject
{
int basicInt;
}
-(void) print;
@end
@implementation basicClass
-(void) print
{
printf("This is the basicClass method, uncooked.\n");
}
@end
@interface anotherClass: basicClass
@end
@implementation anotherClass
-(void) print
{
printf("This is anotherClass method.\n");
}
@end
int main()
{
basicClass *bcObj = [[basicClass alloc] init];
anotherClass *aObj = [[anotherClass alloc] init];
// after this, everything using basicClass will
// actually use anotherClass
[anotherClass poseAsClass: [basicClass class]];
basicClass *basicObject = [[basicClass alloc] init];
[bcObj print];
[aObj print];
[basicObject print];
return 0;
}
The output, demonstrating posing, looks like this:
This is the basicClass method, uncooked.
This is anotherClass method.
This is anotherClass method.
As you can see, the last two objects use the same
print
method, despite being different classes. This happens because of posing.
2 comments:
yeezys
hermes
chrome hearts online store
golden goose
curry 6 shoes
longchamp handbags
yeezy 700
kevin durant shoes
golden goose shoes
jordan shoes
h5y38g9t74 q2s05k5g34 m1o40h4h71 s0y91y4l52 v1v32w3s79 i7b58y8g33
Post a Comment