02.OC类&对象&封装
目录介绍
- 01.类class
- 1.1 类规格说明
- 1.2 类的语法
- 1.3 创建对象
- 1.4 类的继承
- 02.方法
- 2.1 方法分类
- 2.2 方法声明和实现
- 2.3 方法调用
- 2.4 set和get方法
- 03.属性
- 3.1 属性是什么
- 3.2 属性声明
- 04.类别
- 4.1 什么是类别
- 4.2 类别使用
01.类class
1.1 类规格说明
类是 Objective-C 用来封装数据,以及操作数据的行为的基础结构。对象就是类的运行期间实例,它包含了类声明的实例变量自己的内存拷贝,以及类成员的指针。
Objective-C 的类规格说明包含了两个部分:声明interface与实现implementation 。
声明(interface)部分包含了类声明和实例变量的定义,以及类相关的方法。实现(implementation)部分包含了类方法的实际代码。
1.2 类的语法
类的语法由两个部分组成:接口(Interface)和实现(Implementation)。
接口部分(Interface)通常位于头文件(.h)中,用于声明类的属性和方法。它定义了类的公共接口,其他类可以通过引入头文件来访问这些接口。
#import <Foundation/Foundation.h>
@interface MyClass : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
- (void)doSomething;
- (NSInteger)calculateSumWithNumber:(NSInteger)number1 andNumber:(NSInteger)number2;
@end
实现部分(Implementation)通常位于实现文件(.m)中,用于定义类的方法的具体实现。
#import "MyClass.h"
@implementation MyClass
- (void)doSomething {
NSLog(@"Doing something...");
}
- (NSInteger)calculateSumWithNumber:(NSInteger)number1 andNumber:(NSInteger)number2 {
return number1 + number2;
}
@end
1.3 创建对象
Objective-C创建对象需通过alloc以及init两个消息。alloc的作用是分配内存,init则是初始化对象。
init与alloc都是定义在NSObject里的方法,父对象收到这两个信息并做出正确回应后,新对象才创建完毕。以下为范例:
MyClass *my = [[MyClass alloc] init]
需要注意的是,当你使用 alloc 和 init 方法创建对象时,你需要手动释放内存,或者在使用完对象后将其设置为 nil。
1.4 类的继承
通过继承,一个类可以从另一个类派生出来,并继承其属性和方法。被继承的类称为父类或基类,继承的类称为子类或派生类。
首先定义一个父类,定义了一个名为 Vehicle 的父类,它具有品牌和年份属性,并具有启动引擎和停止引擎的方法。
//.h文件
@interface Vehicle : NSObject
@property (nonatomic, strong) NSString *brand;
@property (nonatomic, assign) NSInteger year;
- (void)startEngine;
- (void)stopEngine;
@end
//.m文件
@implementation Vehicle
- (void)startEngine {
NSLog(@"Engine started");
}
- (void)stopEngine {
NSLog(@"Engine stopped");
}
@end
定义了一个名为 Car 的子类,它继承了 Vehicle 类,并添加了一个名为 numberOfDoors 的属性和一个名为 drive 的方法。
//.h文件
@interface Car : Vehicle
@property (nonatomic, assign) NSInteger numberOfDoors;
- (void) drive;
@end
//.m文件
@implementation Car
- (void)drive {
NSLog(@"Car is driving");
}
@end
一个使用继承的示例:
Car *myCar = [[Car alloc] init];
myCar.brand = @"Toyota";
myCar.year = 2022;
myCar.numberOfDoors = 4;
[myCar startEngine];
[myCar drive];
[myCar stopEngine];
02.方法
2.1 方法分类
Objective-C 中的类可以声明两种类型的方法:实例方法和类方法。
实例方法就是一个方法,它在类的一个具体实例的范围内执行。也就是说,在你调用一个实例方法前,你必须首先创建类的一个实例。
而类方法,比较起来,也就是说,不需要你创建一个实例。
2.2 方法声明和实现
方法声明包括方法类型标识符,返回值类型,一个或多个方法标识关键字,参数类型和名信息。
#import <Foundation/Foundation.h>
@interface MyClass : NSObject
- (void)doSomething;
- (NSInteger)calculateSumWithNumber:(NSInteger)number1 andNumber:(NSInteger)number2;
- (NSString *)greetWithName:(NSString *)name;
@end
- doSomething 方法没有返回值(void),也没有参数。
- calculateSumWithNumber:andNumber: 方法返回一个 NSInteger 类型的值,接受两个 NSInteger 类型的参数 number1 和 number2。
- greetWithName: 方法返回一个 NSString 类型的值,接受一个 NSString 类型的参数 name。
2.3 方法调用
当你想调用一个方法,你传递消息到对应的对象。这里消息就是方法标识符,以及传递给方法的参数信息。
发送给对象的所有消息都会动态分发,这样有利于实现Objective-C类的多态行为。
也就是说,如果子类定义了跟父类的具有相同标识符的方法,那么子类首先收到消息,然后可以有选择的把消息转发(也可以不转发)给他的父类。
调用无参数的方法:
[myObject doSomething];
调用带有参数的方法:
NSInteger result = [myObject calculateSumWithNumber:5 andNumber:10];
调用带有返回值的方法:
NSString *greeting = [myObject greetWithName:@"John"];
2.4 set和get方法
可以使用属性(Property)来自动生成 set 和 get 方法,以便于对对象的属性进行设置和获取。
属性声明通常位于类的接口部分(头文件,.h)中。下面是一个属性声明的示例:
@interface MyClass : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end
编译器会自动为这些属性生成对应的 set 和 get 方法。你可以直接使用点语法来设置和获取属性的值。
MyClass *my = [[MyClass alloc] init];
my.name = @"John"; // 使用 set 方法设置属性值
NSString *name = my.name; // 使用 get 方法获取属性值
03.属性
3.1 属性是什么
属性是用来代替声明存取方法的便捷方式。属性不会在你的类声明中创建一个新的实例变量。他们仅仅是定义方法访问已有的实例变量的速记方式而已。
3.2 属性声明
属性通常位于类的接口部分(头文件,.h)中。下面是一个属性声明的示例:
@interface MyClass : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end
属性声明包括以下几个部分:
- @property:用于声明属性。
- (nonatomic, strong):属性的特性修饰符。nonatomic 表示非原子性,strong 表示使用强引用来持有对象。
- NSString *name:属性的类型和名称。
- NSInteger age:属性的类型和名称。
04.类别
4.1 什么是类别
类别(Category)是一种扩展现有类的功能的机制。通过类别,你可以在不修改原始类的情况下,向类添加新的方法。
类别允许你将类的实现分散到多个文件中,以便更好地组织代码。它还可以用于向第三方库或系统类添加自定义方法,而无需修改原始类的源代码。
4.2 类别使用
下面是一个类别的示例:
定义.h头文件
#import "NSString+CustomMethods.h"
// 假设有一个名为 NSString+CustomMethods 的类别文件
@interface NSString (CustomMethods)
- (NSString *)reversedString;
@end
定义.m文件
#import "NSString+CustomMethods.h"
@implementation NSString (CustomMethods)
//反转字符串
- (NSString *)reversedString {
NSMutableString *reversedString = [NSMutableString string];
NSInteger length = [self length];
for (NSInteger i = length - 1; i >= 0; i--) {
[reversedString appendString:[NSString stringWithFormat:@"%c", [self characterAtIndex:i]]];
}
return reversedString;
}
@end
要使用类别中的方法,只需在需要的地方导入类别的头文件,并像调用原始类的方法一样调用类别中的方法:
NSString *originalString = @"Hello, World!";
NSString *reversedString = [originalString reversedString];
NSLog(@"%@", reversedString); // 输出:!dlroW ,olleH