OC语言 - 方法 | 函数
■ 方法 | 函数
我们在设计一个类时只关注三个要素:类名、属性、方法。注:类名的第一个字母大写且不能有下划线或者采用驼峰标识法
类中的每个对象在内存中都占据一定的存储空间,且都有一份属于自己单独的成员变量,所有对象的成员方法在整个内存中也只有一份
每个对象内部都默认有一个 isa 指针,它是对象中的隐藏指针,指向创建该对象的类
代码示例:如何定义一个类
1. 一般地,一个文件对应一个类
// - Person.h:头文件包含了当前类名、父类名、当前类的实例变量、方法声明、属性
1 /* 2 * 实例变量的访问可见度 3 * @public 在该类内部、外部以及其子类都可以访问!它和封装相违背 4 * @private 在该类的内部使用!它和继承相违背 5 * @protected 在该类的内部和子类中使用!默认是受保护的 6 */ 7 #import <Foundation/Foundation.h> 8 // 类名 继承 父类名 9 // | | | 10 @interface Person : NSObject{ 11 @public 12 NSString *_name; 13 NSString *_sex; 14 NSInteger _age; 15 } 16 17 // 方法声明 18 + (void)sayBye; 19 20 @end
// - Person.m:.m 文件是写方法的实现
1 #import "SecondViewController.h" 2 @interface SecondViewController () 3 4 @end 5 6 @implementation SecondViewController 7 8 - (void)viewDidLoad { 9 [super viewDidLoad]; 10 11 } 12 13 14 15 @end 16 17 18 #import "Person.h" 19 @implementation Person 20 // 方法是 OC 独有的一种结构,只能在 OC 中声明、定义和使用 21 // 方法在 C 语言里不能声明、定义和使用 22 23 // 对象方法 24 - (void)saySelf{ 25 NSLog(@"my name : %@,sex : %@,age : %ld",_name,_sex,_age);// 可以直接访问成员变量 26 [self test001]; // 调用对象方法 27 addSum(20, 21); // 调用函数 28 _age;// 访问成员变量 29 30 // 对象方法中的 self 不能调用类方法 31 // [self test002]; // 调用类方法,编译报错 32 } 33 34 // 类方法 35 + (void)sayBye{ 36 NSLog(@"goodbye,sir!%d", addSum(18,30));// 调用函数 37 [self test002];// 调用类方法 38 39 // 类方法中不能直接访问成员变量、不能调用对象方法 40 // _age; // 访问成员变量,编译报错 41 // [self test001];// 调用对象方法,编译报错 42 } 43 44 - (void)test001{ 45 NSLog(@"test001"); 46 } 47 48 + (void)test002{ 49 NSLog(@"test002"); 50 } 51 52 // 函数可以写在 .m 文件的任何位置 53 int addSum(int num1, int num2){ 54 // 函数内部不能访问成员变量 55 // _age; 56 return num1 + num2; 57 } 58 59 @end
self 关键字实质是个指针,只有一个作用:调用自身方法。一般情况下 self 出现在对象方法中则代表对象本身;出现在类方法里面则表示该类
另外成员变量和方法不能用 static 等关键字修饰,这一点不要同 C 语言混淆
2. 一个文件也可以定义多个类(不建议这么搞)
// - MultipleClass.h:该文件中定义了 Car 和 Animal 两个类
1 #import <Foundation/Foundation.h> 2 // Car 3 @interface Car : NSObject{ 4 @public 5 NSString *_brand;// 品牌 6 NSString *_color;// 颜色 7 CGFloat _price;// 价格 8 } 9 10 -(void)run; 11 12 @end 13 14 // Animal 15 @interface Animal : NSObject{ 16 @public 17 NSString *_name; // 昵称 18 CGFloat _age; // 年龄 19 NSString *_color;// 毛色 20 } 21 22 -(void)call; 23 24 @end
// - MultipleClass.m
1 #import "MultipleClass.h" 2 // Car 3 @implementation Car 4 5 -(void)run{ 6 NSLog(@"一辆轿车,牌号是%@,颜色是%@,价格是%.2f",_brand,_color,_price); 7 } 8 9 @end 10 11 // Animal 12 @implementation Animal 13 14 // 重写父类方法,实现赋值 15 -(id)init{ 16 _name = @"蛮妞"; 17 _age = 1.2; 18 _color = @"土豪金"; 19 return self; 20 } 21 22 -(void)call{ 23 NSLog(@"我是一只波斯猫,我的名字是%@,毛色是%@,年龄是%.2f岁",_name,_color,_age); 24 } 25 26 @end
3. 如何使用定义过的类
// - main.m
1 #import <Foundation/Foundation.h> 2 #import "Person.h" 3 #import "MultipleClass.h" 4 int main(int argc, const char * argv[]) { 5 6 // Person 实例 7 Person *p = [Person alloc]; 8 9 // 对象的创建分两步执行 10 // 1. 分配内存:+(id)alloc 11 // alloc 的过程会在堆区开辟一块内存来存储所有的实例变量 12 // 内存大小和实例变量所占的内存总和有关系 13 // 它在堆内存中创建了该类的对象,返回未初始化的对象 14 // 2. 初始化:-(id)init 15 // init 的过程会把对象、实例变量进行初始化,返回一个已初始化的对象 16 17 Person *p01 = [[Person alloc] init]; 18 // 访问成员变量 19 // 方式一 20 p01->_name = @"Hazell"; 21 p01->_age = 21; 22 // 方式二 23 (*p01)._sex = @"female"; 24 [Person sayBye]; 25 26 // 一个类可以创建多个对象 27 Person *p02 = [[Person alloc] init]; 28 p02->_name = @"Jane"; 29 p02->_age = 25; 30 p02->_sex = @"female"; 31 NSLog(@"P02 name : %@,p2 sex : %@,p2 age : %ld",p02->_name,p02->_sex,p02->_age); 32 33 //------------------------------------------------------------ 34 35 Car *car = [[Car alloc] init]; 36 car->_brand = @"BMW"; 37 car->_color = @"玫瑰金"; 38 car->_price = 888888.88; 39 [car run]; 40 41 Animal *cat = [[Animal alloc] init]; 42 [cat call]; 43 44 return 0; 45 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律