【Objective-C 入门】2.类的声明、实现和实例化
概述
本文在 Xcode 环境下完成了声明、定义、实例化一个 Objective-C 类的全流程,以此描述 Objective-C 类的语法,是 Objective-C 入门记录中的一篇。
本文的相关内容参考了《Objective-C入门教程》(作者:传智播客高教产品研发部)
阅读本篇之前,你应该至少:
如果你已经了解了下面这些内容,阅读起来会更加顺畅:
- 曾经学习过一些具有面向对象特性的语言的语法(例如 C++)
类的声明和实现
完整地定义一个类需要创建 类的声明(.h 文件)和 类的实现(.m 文件)两个部分。
分离类的声明和实现是为了封装类的实现细节和内部构造,从而在制成静态库供给第三方使用时,导入库包只能查阅 .h 文件,使得源代码具有更强的独立性和安全性。
类的声明
类的声明通常存放在 .h 后缀的文件中,仅描述参数和接口,而不涉及任何借口的具体实现,其语法格式如下。
@interface _ClassName_ : _ParentClassName_
{
_VariableDeclaration_
}
_MethodDeclaration_
@end
类的实现
类的实现通常放置在 .m 后缀的文件中,文件名与对应的 .h 文件相同,他进行了类的声明中所有方法的具体实现,其语法格式如下:
@implementation _ClassName_
_ImplementationOfMethod_
@end
声明和实现的例子
在 Xcode 中实现一个学生类以更好地理解语法格式。
新建一个 Cocoa Class
,并按下图所示设置,点选确定后可以选择生成文档的位置和绑定到的项目。
Student.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Student : NSObject
{
// 'public' keyword makes variable can be accessed by the outside
@public
float weight; // declare weight
int age; // declare age
}
-(void) Eat; // Eat method
@end
NS_ASSUME_NONNULL_END
在 Xcode 生成的 Student.h 文件中可以看到这样两个宏:
NS_ASSUME_NONNULL_BEGIN
和 NS_ASSUME_NONNULL_END
这两个宏是规定属性不可为空的,详细的内容可以在这篇博客中看到:NS_ASSUME_NONNULL_BEGIN
@public
关键字让之后的两个变量weight
和age
可以被外界访问-(void)Eat
声明了吃饭的方法,他同样可以直接访问上面声明的两个变量。
Student.m
#import "Student.h"
@implementation Student
-(void) Eat
{
NSLog(@"Age:%d, Weight:%f", age, weight);
}
@end
这一段在 Student.m 中具体实现了在 .h 文件中声明的 Eat
方法。
类的实例化
在 OC(Objective-C) 中,根据类创建对象实例的方式有两种
第一种方式
_ClassName_ *_InstanceName_ = [_ClassName_ new];
- 举例创建一个 Student 类的实例对象:
Student *stu = [Student new];
这一行的执行流程是使用 new
关键字创建实例对象后,将对象的内存地址赋值给等号左侧的指针变量。
第二种方式
_ClassName_ *_InstanceName_ = [[_ClassName_ alloc] init];
- 举例创建一个 Student 类的实例对象:
Student *stu = [[Student alloc] init];
执行流程是通知类使用 alloc
方法为对象分配一块内存,并调用 init
方法对对象进行初始化,然后对象的内存地址赋值给等号左侧的指针变量。
教程上说虽然创建对象有两种方式,并且
new
的内部也调用了alloc
和init
,但仍推荐使用第二种方式。
探究这个推荐的原因,参考了这篇文章:iOS 初始化方法 alloc init 与 new 的区别,下面是这篇文章的结论部分。总的来说,两种方式创建对象现在基本上一样,区别就是使用new只能默认init进行初始化,alloc方式可以使用其它的init开头的方法进行初始化。
还有一点,在其实默认的init方法中 , 什么都没有做,直接返回了self , 所以,如果没有重写init的话, [Class alloc] 和 [[Class alloc]init] 是等价的。
挖一个消息机制的坑:
使用一个类生成实例对象,使用的机制是向类发送消息(Message),这是 OC 区别于 C++, Java 等其他面向对象编程语言的机制。
挖一个在 main 函数中具体调用一个类的实例的坑,用来完善这一篇教程。
另外,Student 类的基类是 NSObject 类,这个类是 Objective-C 中大部分类的基类,作为入门教程暂时到此为止,以后研究到相关内容的时候来填坑。
还有挖一个讲解类的各种定义的作用域的坑。