Objective-C 2.0 with Cocoa Foundation

从 -C 名称可以看出,这是一种面向对象的语言。面向对象最基本的元素之一是类的概念,-C 也不例外。所谓类的概念,其实是从C语言的结构发展而来的。我们知道,C语言中的结构体只有数据的概念,而面向对象语言不仅支持数据,还在结构体中封装了访问结构体数据的方法。结构体的数据和方法组合在一起,我们称整个结构体为一个类。只有一个类,我们不能执行任何操作。我们必须使课程具体化。我们称物化类对象()。从这个角度来看,我们可以将类视为对象的模板。

如果我们想使用一个类,我们必须声明这个类,类似于构造函数。

请参考“.h”文件:

1#

2

3

4@:{

;

6}

7-(无效);

8-(void):(int)count;

9@结束

如果你看过这个系列的第二章,第一行应该是一张老面孔。我们知道,我们需要这个东西来免费获得苹果为我们精心准备的很多功能。没有这个东西,我们的工作会很复杂。

同学们,请看第4行和第9行的第一个字母,“@”符号又出现了。为什么再说一遍,因为我们在第2章的字符串之前也看到了这个东西。这个符号出现在字符串的前面是因为我们需要将它与C语言的字符串定义区分开来,并且需要编译器的指导。在这里,我想告诉同学们的是,这里的“@”符号的作用还是面向编译器的。我们知道 Java 和 C++ 定义了一个关键字 class 来声明一个类。在 -C 中,没有这样的关键字。-C中,类定义从@开始,到@end结束,也就是说编译器看到@就知道这是类定义的开始,看到@end就知道类定义结束.

我们这里的类名是””,我们用空格和@分隔,告诉编译器我们要声明一个类被调用。在后面,我们有“:”,这是告诉编译器我们继承的是继承。关于继承和求和,我们将在后面的章节中详细介绍。我们现在可以将“:”理解为,通过这种方式,我们免费获得了苹果为我们精心准备的一系列类和对象的必要方法。称为根类,即根类。在 Java 或 .NET 中,根类是必须的,但在 C++ 中不是。在-C中,原则上可以不使用自己构建一个根类,但实际上这样做会很费功夫,而且没有多大意义,因为苹果已经为你提供了很长时间的考验。可能好奇的同学都想自己建根班,但至少我不会有自己建根班的欲望。

好的,我们现在去第 5 行。我们曾经把这个东西称为变量。从现在开始,我们需要使用确切的术语 -C,它是一个实体变量( ,在一些英文资料中将缩写为 iVars )。虽然作为一,它有不止一个实体变量,比如体重等,但是为了代码简洁,我们这里声明一为牛腿数,即牛股数。这个实体变量是int类型,代表一个整数。当然,我们不希望有 4.5 个牛腿。

我们看第6行。第6行的括号和第4行的最后一个括号是用来表示实体变量的定义区间的。编译器认为这两个括号之间的定义是实体变量的定义。当然,如果你的类没有实体变量,那么这两个括号之间是不允许的。与 Java 和 C++ 不同,-C 要求括号中不能有方法,即函数定义。那么-C中方法的定义应该放在哪里呢?见第 7 行。

第 7 行的第一个字母是减号“-”。这个减号告诉编译器减号后面的方法是一个实体方法( )。实体方法意味着该方法在类没有被实例化之前不能运行。我们这里看到的是减号,有减号的时候有加号。我们把加号的方法称为类方法(class),它对应于实体方法,类方法可以在没有实体的情况下运行。关于类方法,我们将在后面的章节中解释。您可能还记得 C++ 和 Java 也有类似的区别,对吧?

-C 中方法的返回类型需要用括号括起来。当编译器看到减号或加号后面的括号时,会认为这是声明方法的返回值。您也可以不声明返回值。-C 编译器将向函数添加默认返回值,而无需显式返回值。它的类型是 id。id类型我们后面会解释,但是作者不推荐。返回值的类型不写。

在第 7 行,我们定义了这个方法的名称。当然,我们人类无法理解我们所说的话。我只是希望它输出一些我们可以在控制台中理解的字符串。在方法声明的末尾,需要一个分号来标识它,它与 C 保持相同。

让我们再看一下第 8 行。第 8 行和第 7 行有更多的“:(int)count”。方法后面的冒号用来表示该变量是用来定义变量的。变量的类型也用括号括起来。如果变量的类型没有写,编译器也认为它是一个id类型。最后一个计数是变量的名称。如果有多个变量怎么办?答案是在第一个变量后加一个冒号,然后在变量类型周围加上括号,然后是变量名。

好了,我们总结到这里,类的定义方法如下:

@类名:父类名{

实体变量类型实体变量名;

}

-(返回值类型)方法名;

+(返回值类型)方法名;

-(返回值类型)方法名称:(变量类型)变量名称标签1:(变量类型)变量1名称;

@结尾

…的含义在本系列的介绍性讲座中,…的意思是省略了一些代码。

3.4、类的定义

我们在上一节中介绍了类声明,接下来我们将看看类定义。要求学生打开“.m”文件:

1#”.h”

2

3

4@

5-(无效)

6{

(@”你好,,我有%dlegs.”,);

8}

9-(void):(int)count

10{

=计数;

12}

13@结束

14

.m文件的第一行是.h文件,和C的机制是一样的,#的说明请参考第二章。

我们看第4行和第13行。和头文件中的@一样,我们这里的类的定义也是使用的编译指南。编译器将 @ 到 @end 的部分视为类定义。@ 后面有一个空格,空格后面的类名是告诉编译器我们要定义一个类。第4行和第13行之间是我们在头文件中定义的实体方法或类方法的定义部分。当然,如果我们的类没有实体方法和类方法,也可以写@和@end,中间留空即可。

第5行是我们定义的实现,可以发现第5行的内容和头文件.h的第7行是一致的。笔者个人认为,在编写实体方法和类方法的定义时,为了避免手动输入造成的错误,可以从头文件中复制声明的部分,然后删除分号,加上两个大括号。我们知道第 6 到第 8 行是方法定义的一部分,我们来看第 7 行。第 7 行类似于第 2 章中的 Hello, World 输出,只是多了一个 %d 和实体变量。这种写法与C语言类似,将用于替换输出中的字符串。%d。

第9行的内容与.h的第8行相同,这里不再赘述。让我们看一下第 11 行。第 11 行是说,将参数 count 的值赋给实体变量。我们可以通过方法来控制对象内部的值。

这部分的重点是@和@end。明白了这件事之后,剩下的就不难理解了。让我们总结一下类的定义部分的语法:

@班级名称

-(方法返回值)方法名

{

方法定义

}

-(方法返回值)方法名:(变量类型)变量名

{

方法定义

}

@结尾

3.5、类的实例化

我们分别在 3.3 和 3.4 部分声明和定义一个类。虽然定义了类,但我们不能直接使用这个类。因为类的内容需要传入内存,我们称之为内存分配(),然后实体变量需要初始化()。当这些步骤结束后,我们的类就被实例化了,我们把实例完成的类称为()。好的,现在我们知道了在类实例化过程中需要做什么,让我们看看我们得到的类定义和声明是如何被实例化的。

1#

2#”.h”

3

(,*argv[]){

*池=[[oc]init];

6

=[];

8[:4];

9[];

10

11[];

;

13}

同学们,请看第7行的第一个单词id。id是英文的缩写。我们在很多地方都遇到过id。比如在博客园里,我们都是用id来登录系统的,我们的id代表系统的一个用户。由于 id 在系统中是唯一的,因此系统在获得我们的 id 后就知道我们是谁。-C 也是如此。使用 id 来表示一个对象。在 -C 中,所有对象都可以通过 id 来区分。我们知道一个类只是一些数据加上操作数据的代码,所以id实际上是一个指向数据结构的指针,相当于void*。

第 7 行的第二个单词是我们给 id 的名称。当然,您可以使用系统保留名称以外的任何名称,但是为了保持代码的可读性,我们需要一个有意义的名称,这里我们使用初始文本为小写。

第7行的[]是创建对象,new其实是alloc和init的结合,而-C中创建对象是一个分配内存和初始化对象的过程。new、alloc 和 init 在超类中定义。作者将在第 7 章详细解释如何创建对象。直到第 7 章我们使用 new 来创建对象。

-C 中方法的使用与其他语言有点不同,-C 使用 () 来调用方法。因此,笔者认为,在解释第7行等号右边的部分之前,我们需要先介绍一下我们的一个新朋友,news()。消息是类或对象可以执行的操作。消息的格式如下:

【对象或类名方法名:参数序列】;

首先我们观察到有两个方括号,最右边的括号后面是一个分号,当编译器遇到这种格式时,会将中间部分作为消息发送出去。上述表达式中,包括方括号在内的所有部分的内容都称为消息表达式(),“对象或类名”称为接收者(),即消息的接收者,“方法名:参数序列”称为 (),“方法名”称为 () 或 ()。-C和C语言完全兼容。C语言中的方括号是用来表示数组的,但是数组的格式与发送的消息格式明显不同,所以我们可以放心编译器不会发送我们的消息。作为数组发送。

让我们回顾一下C语言中函数的调用过程。实际上,编译器在编译的时候就已经确定了函数相对于整个执行包的入口地址。函数的执行实际上是直接从这个地址执行的。. -C 使用间接方式。-C 向对象或类发送消息(具体来说,对象或类的名称取决于方法是实体方法还是类方法)。消息的格式应与方法的格式相同。具体来说,第 7 行等号右侧的 [] 部分表示向该类发送了一条新消息。这样,当类接收到new时,它会查找它可以对应的消息列表。找到new后会调用new类方法,分配内存,初始化后返回一个id,

-C 在编译过程中,编译器会检查方法是否有效,如果无效,会给出警告。但编译器不会阻止你执行,因为消息只有在执行时才会触发,编译器无法预测执行时会发生什么奇妙的事情。使用这样的机制无疑会给程序带来很大的灵活性,因为我们可以向任何对象或类发送消息,只要保证类在执行时能够准确的找到消息并执行即可,当然,如果是找不到,操作会失败。

一切一分为二——

一切都一分为二,当我们获得灵活性时,我们就会失去执行时间。-C的这种方法比直接从函数入口地址执行的方法消耗更多的执行时间,虽然编译器在一定程度上优化了搜索过程。

有同学会觉得奇怪,我们没有在里面定义new,能不能把这个类的方法发给它呢?答案是肯定的,因为 new 就在其中,而且它实际上响应了新消息。事实上,new 类似于一个宏,而不是一个“原子”不可分割的方法。我们将在后续章节中解释细节。

有了第7行的解释,就不难理解第8行的内容了。第8行其实是对象发送的消息。参数为4。参考.m,我们可以发现此时我们想要实体变量。是4。第8行就更简单了,就是给对象发送消息,从而实现控制台的输出。

3.6,章节摘要

通过本章的学习,学生应掌握以下概念

如何声明一个类 如何定义一个类 实体变量定义 类方法和实体方法定义 id 有什么奇妙的作用 我们将在下一章介绍继承的概念。

分类:

技术要点:

相关文章:

© 版权声明
THE END
喜欢就支持一下吧
点赞285赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容