3.5,类的实例化
我们在3.3和3.4节里面分别声明和定义了一个cattle的类。虽然定义好的类,但是我们是不能直接使用这个类的。因为类的内容需要被调入到内存当中我们称之为内存分配(Allocetion),然后需要把实体变量进行初始化(Initialization),当这些步骤都结束了之后,我们的类就被实例化了,我们把实例化完成的类叫做对象(objecs)。好的,我们知道了我们在类的实例化过程当中需要做哪些工作,我们接着来看看我们已经搞定的cattle类的定义和声明是怎样被实例化的。
1 #import
2 #import "cattle.h"
3
4 int main (int argc, const char * argv[]) {
5 NSautoreleasePool * pool = [[NSautoreleasePool alloc] init];
6
7 ID cattle = [cattle new];
8 [cattle setLegsCount:4];
9 [cattle saySomething];
10
11 [pool drain];
12 return 0;
13 }
同学们请看第7行的第一个单词ID。 ID是英文IDentifIEr的缩写,我们在很多地方都遇到过ID,比如说在博客园里面,我们都使用ID来登陆系统的,我们的ID就代表着系统的一个用户。由于ID在一个系统当中是唯一的,所以系统获得我们的ID之后就知道我们是谁了。objecsive-C也是一样的道理,使用ID来代表一个对象,在objecsive-C当中,所有的对象都可以使用ID来进行区分。我们知道一个类仅仅是一些数据外加上 *** 作这些数据的代码,所以ID实际上是指向数据结构的一个指针而已,相当于voID*。
第7行的第二个单词是cattle,就是我们给这个ID起的一个名字。当然,你可以起系统保留的名字以外的任何名字,不过为了维持代码的可读性,我们需要一个有意义的名字,我们这里使用头文字为小写的cattle。
objecsive-C里面的方法的使用和其他语言有些不同,objecsive-C使用消息(Message)来调用方法。所以笔者认为在讲解第7行等号右边的部分之前,需要首先向大家介绍一个我们的新朋友,消息(Message)。所谓的消息就是一个类或者对象可以执行的动作。消息的格式如下:
[对象或者类名字 方法名字:参数序列];
首先我们观察到有两个中括弧, 最右边的括弧之后是一个分号,当编译器遇到了这个格式之后会把中间的部分当作一个消息来发送。在上文的表达式当中,包括中括弧的所有部分的内容被称作消息表达式(Message Expression),“对象或者类名字”被称作接收器(Receiver),也就是消息的接受者,“方法名字:参数序列”被称为一个消息(Message),“方法名字”被称作选择器(Selector)或者关键字(Keyword)。objecsive-C和C语言是完全兼容的,C语言里面的中括弧用于表示数组,但是数组的格式明显和消息的发送的格式是不一样的,所以我们可以放心,编译器不会把我们的消息发送当作一个数组。
我们来回忆一下C语言里面函数的调用过程,实际上编译器在编译的时候就已经把函数相对于整个执行包的入口地址给确定好了,函数的执行实际上就是直接从这个地址开始执行的。objecsive-C使用的是一种间接的方式, objecsive-C向对象或者类(具体上是对象还是类的名字取决于方法是实体方法还是类方法)发送消息,消息的格式应该和方法相同。具体来说,第7行等号右边的部分[cattle new]就是说,向cattle类发送一个new的消息。这样当cattle类接收到new的时候,就会查找它可以相应的消息的列表,找到了new之后就会调用new的这个类方法,分配内存和初始化完成之后返回一个ID,这样我们就得到一个对象。
objecsive-C在编译的过程当中,编译器是会去检查方法是否有效的,如果无效会给你一个警告。但是编译器并不会阻止你执行,因为只有在执行的时候才会触发消息,编译器是无法预测到执行的时候会发生什么奇妙的事情的。使用这样的机制给程序毫无疑问将给带来极大的灵活性,因为我们和任意的对对象或者类发送消息,只要我们可以保证执行的时候类可以准确地找到消息并且执行就可以了,当然如果找不到的话,运行会出错。
任何事物都是一分为二的 ---
任何事物都是一分为二的,在我们得到了灵活性的时候我们损失的是执行的时间。objecsive-C的这种方式要比直接从函数的入口地址执行的方式要消耗更多的执行时间,虽然编译器对寻找的过程作过一定的优化。
有的同学会觉得奇怪,我们在cattle里面并没有定义new,我们可以向cattle发送这个类方法么?答案是可以,因为new在NSobjecs里面,实际上响应new消息的是NSobjecs。实际上new类似于一个宏,并不是一个“原子”的不可再分的方法,关于详细的情况,我们将在后续的章节里面讲解。
有了第7行的讲解,那么第8行的内容就不难理解了,第8行实际上是想cattle对象发送一个setLegsCount的消息,参数是4,参照Catttle.m,我们可以发现这个时候我们希望实体变量legsCount是4。第8行就更简单了,就是说向cattle对象发送一个saySomething的消息,从而实现了控制台的输出。
总结以上是内存溢出为你收集整理的Objective-C 2.0 with Cocoa Foundation --- (类的声明和定义 3)全部内容,希望文章能够帮你解决Objective-C 2.0 with Cocoa Foundation --- (类的声明和定义 3)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)