【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_BEGINNS_ASSUME_NONNULL_END
这两个宏是规定属性不可为空的,详细的内容可以在这篇博客中看到:NS_ASSUME_NONNULL_BEGIN

  • @public 关键字让之后的两个变量weightage可以被外界访问
  • -(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 的内部也调用了 allocinit ,但仍推荐使用第二种方式。
探究这个推荐的原因,参考了这篇文章: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 中大部分类的基类,作为入门教程暂时到此为止,以后研究到相关内容的时候来填坑。
还有挖一个讲解类的各种定义的作用域的坑。

posted @ 2021-11-28 21:39  ParallelParadox  阅读(266)  评论(0编辑  收藏  举报