!!!Obj-C 2.0 -- Chapter 2 Defining a Class

In Objective-C, classes are defined in two parts:

  • An interface that declares the methods and instance variables of the class and names its superclass.
  • An implementation that actually defines the class.

These two parts usually split between two files, but we can also use category to use several files to define a class.

2.1 Source Files

The interface and implementation are usually separated into two different files. The interface file must be made available to anyone who uses the class.

It's customary to have a separate interface file for each class.

2.2 Class Interface

The declaration of a class interface begins with the compiler directive @interface and ends with the directive @end

@interface ClassName : ItsSuperclass
{
    instance variable declarations
}
method declarations
@end
Methods are declared after the braces enclosing instance variables and before the end of the class declaration.

The names of methods that can be used by class objects, class methods, are preceded by a plus sign:

+ alloc;
The methods that instances of a class can use, instance methods, are marked with a minus sign:

- (void) display;
Different between class/instance method: http://stackoverflow.com/questions/1053592/what-is-the-difference-between-class-and-instance-methods
Class method and instance method can have the same name. A method can have the same name as an instance variable.

Method return types and argument types are declared using the standard C syntax:

- (void)setRadius:(float)aRadius;
If a return or argument type isn't explicitly declared, it's assumed to be the default type for methods and messages --- an id.

When there's more than one argument, the arguments are declared within the method name after the colons:

- (void)setWidth:(float)width height:(float)height;

2.2.1 Importing the interface

The interface file must be included in any source module that depends on the class interface. The interface is usually included with the #import directive

#import "Rectangle.h"
#import is similar to #include, except that it makes sure the same file is never included more than once.

An interface file begins by importing the interface for its superclass:

#import "ItsSuperclass.h"
@interface ClassName : ItsSuperclass
{
    ......
}
......
@end

2.2.2 Referring to Other Classes

If the interface file mentions a class that is not in the hierarchy, it must:

1. import them explicitly

2. declare them with the @class directive

// inform compiler that Rectangle/Circle are class names
@class Rectangle, Circle;
An interface file mentions class names when it statically types instance variables, return values, and arguments:

//mentions NSColor class
- (void)setPrimaryColor:(NSColor *)aColor;
In the above case, we only need to know that NSColor is a class name, so @class directive gives the compiler sufficient forwarning of what to expect.

2.3 Class Implementation

The definition of a class begins with the @implementation directive and ends with the @end directive.

Every implementation file must import its own interface:

#import "ClassName.h"

@implementation ClassName
method definition
@end
Methods for a class are defined within a pair of braces:

+ (void)setFilled: (BOOL)flag
{
    ....
}

2.3.1 Referring to Instance Variables

By default, the definition of an instance method has all the instance variables of the object within its scope. It can refer to them simply by name:

- (void)setFilled: (BOOL) flag
{
    filled = flag;
    ...
}
When the instance variable belongs to an object that's not the receiver, the object's type must be made explicit to the compiler through static typing. In referring to the instance variable of a statically typed object, the structure pointer operator(->) is used.

2.3.2 The Scope of Instance Variables

An object's interface lies in its methods, not in its internal data structures.

To enforce the ability of an object to hide its data, the compiler limits the scope of instance variables.

DirectiveMenaing
@privateThe instance variable is accessible only within the class that declares it
@protectedThe instance variable is accessible within the class that declares it and within classes that inherit it.
@public The instance variable is accessible everywhere
@packageOn 64-bit, an @package instance variable acts like @public inside the image that implements the class, but @private outside.
This is most useful for instance variables in framework classes, where @private may be too restrictive but @protected or @public too permissive.
By default, all unmarked instance variables are @protected. ( In C++, class is private; struct is public)

A directive applies to all the instance variables listed after it, up to the next directive or the end of the list.

Instance variables marked @private are only available to subclasses by calling public accessor methods, if they exist.

Normally, to get information stored in an instance variable, other objects must send a message requesting it. However, a public instance variable can be accessed anywhere as if it were a field in a C structure:

Worker *ceo = [[Worker alloc] init];
ceo->boss = nil;
Public instance variables should be avoided except in extraordinary cases.

2.4 Messages to self and super

Objective-C provides two terms that can be used within a method definition to refer to the object that performs the method ---selfand super.

As receivers, self/super differ principally in how they affect the messaging process:

  • self searches for the method implementation in the usual manner, starting in the dispatch table of thereceiving object's class.
  • super begins in the superclass of the class (that defines the method where super appears).

Difference-between-self-and-super: http://stackoverflow.com/questions/5673230/objective-c-difference-between-self-and-super

In both cases they are specifying where the search for a method should start, in the case ofself the starting point is determined dynamically, in thesuper case it is known at compile time.

2.4.1 Example

High/Mid/Low define three different versions of negotiate method. Mid defines a method called makeLastingPeace.


if makeLastingPeace use self:

- makeLastingPeace
{
    [self negotiate];
}

[HighObject makeLastingPeace];  //will use high's negotiate
[MidObject makeLastingPeace];   //will use Mid's negotiate
[LowObject makeLastingPeace];   //will use Low's negotiate 
if makeLastingPeace use super:

//makeLastingPeace is defined in Mid class, so the super class
//is High
- makeLastingPeace
{
    [super negotiate];
}

[HighObject makeLastingPeace];  //will use high's negotiate
[MidObject makeLastingPeace];   //will use high's negotiate
[LowObject makeLastingPeace];   //will use high's negotiate 

2.4.2 Using super

Messages to super allow method implementations to be distributed over more than one class.

Each class in the inheritance hierarchy can implement a method that does part of the job and passes the message on to super for the rest.

Each init method has responsibility for initializing the instance variables defined in its class. But before doing so, it sends an init message to super to have the classes it inherites from initialize their instance variables:

- (id)init
{
    if(self = [super init])
    {
        ...
    }
}

2.4.3 Redefining self

Super is only used to tell compiler where to begin search for the method to perform.

self is a variable name that can be used in any number of ways, even assigned a new value.

Inside an instance, self refers to the instance; but inside a class method, self refers to the class object.

// a bad example
+ (Rectangle *)rectangleOfColor: (NSColor * color)
{
    self = [[Rectangle alloc] init];    //bad
    [self setColor: color];
    return [self autorelease];
}
It's usually better to use a variable other than self to refer to an instance inside a class method:

// a good example
+ (id)rectangleOfColor: (NSColor * color)
{
    id newInstance = [[Rectangle alloc] init];    //good
    [newInstance setColor: color];
    return [newInstance autorelease];
}
In fact, rather than sending the allocmessage to the class in a class method, it's often better to send alloc to self. If the class is subclassed, and rectangleOfColor: message is received by a subclass, the instance returned will be the same type as the subclass:

// a good example
+ (id)rectangleOfColor: (NSColor * color)
{
    id newInstance = [[self alloc] init];    //good
    [newInstance setColor: color];
    return [newInstance autorelease];
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值