定义类2

本文深入探讨了 Objective-C 类的实现细节,从类声明到方法定义,再到实例变量的使用和作用域,全面展示了类定义的语法和实例变量的可见性。通过具体的代码示例,解释了类方法如何引用实例变量,以及如何通过编译指令控制实例变量的作用域。强调了不同作用域范围的重要性,并讨论了公共、保护和私有实例变量的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Class Implementation

The definition of a class is structured very much like its declaration. It begins with an@implementationdirective and ends with the@enddirective. In addition, the class may declare instance variables in braces afterthe@implementationdirective:

@implementation ClassName  //类声明的语法
{
    // Instance variable declarations.
}   //类定义中也可以声明实例变量,但通常通过声明properties 来实现,所以{} 可以omit
// Method definitions.
@end


Instance variables are often specified by declared properties (see“Declared Properties”(page 62)). If you don’tdeclare additional instance variables, you can omit the braces:

NoteEvery implementation filemust  import its  own  interface.Forexample,Rectangle.m  imports   Rectangle.h.Because the implementation doesn’t need to repeat any of the declarations it imports,it can safely omit the name of the superclass.

Methods for a class are defined, like C functions, within a pair of braces. Before the braces, they’re declared inthe same manner as in the interface file, but without the semicolon. For example:

@implementation ClassName
// Method definitions.   
//方法的实现定义
+ (id)alloc {
    ...

}

- (BOOL)isFilled {
    ...

}

- (void)setFilled:(BOOL)flag {
    ...

}

 
@end



Referring to Instance Variables

By default, the definition of an instance method has all the instance variables of the object within its scope.

Itcan refer to them simply by name. Although the compiler creates the equivalent of C structures to store instance variables,

the exact nature of the structure is hidden. You don’t need either of the structure operators (. or->) to refer to an object’s data.

通常方法的定义中所以的实例变量都是可见的,直接使用名称就可以引用到了,虽然编译器会创建等价的C 结构去存储其实例变量,

但这个结构是隐藏的,我么也没必要引用到。

For example, this method definition refers to the receiver’s filled instancevariable:

- (void)setFilled:(BOOL)flag
{
    filled = flag;

...}

Neither the receiving object nor its filled instance variable is declared as a parameter to this method, yet the instance variable falls

within its scope.

This simplification of method syntax is a significant shorthand inthe writing of Objective-C code.



When the instance variable belongs to an object that’s not the receiver, the object’s type must be made explicitto the

compiler through static typing. In referring to the instance variable of a statically typed object, thestructure pointer operator (->)

is used.

Suppose, for example, that the Sibling class declares a statically typed object, twin, as an instance variable:

@interface Sibling : NSObject
{
    Sibling *twin;
    int gender;
    struct features *appearance;

}

As long as the instance variables of the statically typed object are within the scope of the class

(as they arehere because twin is typed to the same class), a Sibling method can set them directly:



- makeIdenticalTwin
{
       if ( !twin ) {
        twin = [[Sibling alloc] init];
        twin->gender = gender; //需要使用结构指针->引用其成员变量。 故而
                                                           //twin 需要静态类型绑定
        twin->appearance = appearance;

}

    return twin;
}


The Scope of Instance Variables P40

To enforce the ability of an object to hide its data, the compiler limits the scope of instance variables—that is,limits their

visibility within the program. But to provide flexibility, it also lets you explicitly set the scope at four levels.

Each level is marked by a compiler directive:

通过编译指令可以实现对实例变量作用域范围的控制,从而实现

Directive

Meaning

@private

The instance variable is accessible only within the class that declares it. 自己可见

@protected

The instance variable is accessible within the class that declares it and within classesthat inherit it. All instance variables without an explicit scope directive have @protectedscope. 继承我的都可见,如果没显式指定,则这个

是默认的范围

@public

The instance variable is accessible everywhere. 完全公开

@package

Using the modern runtime, an @package instance variable has @public scope inside the executable image that implements the class, but acts like @private outside. 在可执行文件内继承该类的都可见,但其他都不可见,奇怪

跟@protected 有什么区别?需要试验???、

The @package scope for Objective-C instance variables is analogous [相似的]to private_extern for C variables and functions. Any code outside the class implementation’s image that tries to use the instance variable gets a link error.

This scope is most useful for instance variables in framework classes, where @privatemay be too restrictive but @protected or @public too permissive.





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

In the following example, the age and evaluation instance variables are private; name, job, and wageare protected;

and boss is public.

@interface Worker : NSObject
{
    char *name;  默认就是@protected
@private    //注意虽然跟C++有点像,但没有分号

int age;

    char *evaluation;
@protected

id job;

    float wage;
@public

id boss;}

By default, all unmarked instance variables (like name above) are @protected.



All instance variables that a class declares, no matter how they’re marked, are within the scope of

the classdefinition. For example, a class that declares a job instance variable,

such as the Worker class shown above,can refer to it in a method definition:

- promoteTo:newPosition
{
    id old = job; ///不管实例变量声明成什么范围,但在类的方法定义里,都是可见的
    job = newPosition;
    return old;

}

Obviously, if a class couldn’t access its own instance variables, the instance variables would be of no use what soever.


通常对于继承过来的实例变量,也是能访问的。

Normally, a class also has access to the instance variables it inherits. The ability to refer to an instance variableis usually inherited

along with the variable. It makes sense for classes to have their entire data structures within their scope, especially if you think of

a class definition as merely an elaboration of the classes it inherits from.The promoteTo: method illustrated earlier could just as

well have been defined in any class that inherits the job instance variable from the Worker class.



However, there are reasons why you might want to restrict inheriting classes from directly accessing an instance variable:

Once a subclass accesses an inherited instance variable, the class that declares the variable is tied to that part of

its implementation. In later versions, it can’t eliminate the variable or alter the role it plays without in advertently breaking

the subclass.


Moreover, if a subclass accesses an inherited instance variable and alters its value, it may inadvertently introduce bugs

in the class that declares the variable, especially if the variable is involved in class-internal dependencies.


To limit an instance variable’s scope to just the class that declares it, you must mark it @private. Instance variables

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

At the other extreme, marking a variable @public makes it generally available, even outside of class definitions that

inherit or declare the variable. 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 any where as if it were a

field in a C structure. For example:

  Worker *ceo = [[Worker alloc] init];

ceo->boss = nil;// public类型的实例变量通过指针就可以访问到了,注意需要静态指定类型,但如果声明为private3的话,则只能给相应的公共访问方法发送访问消息。



Note that the object must be statically typed.


使用public将破坏对象的封装性,也就是暴露其数据。

Marking instance variables @public defeats [挫败, 使落空]the ability of an object to hide its data.

It runs counter to a fundamental principle of object-oriented programming—the encapsulation [ 包装,封装;包裹]

of data within objects where it’s protected from view and in advertent [注意的,留意的] error. Public instance

variables should therefore be avoided except inextraordinary cases.

因此除非特殊情况,否则避免使用public










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值