OC语法基本使用
首先来了解一下:
1.面向过程与面向对象
1.1面向过程编程
什么是面向过程?
Procedure,流程;
主干流程和分支流程;
子模块,代码的复用;
特点:所有的工作,一个人干,不利于工程协作;
1.2 类和对象
1.2.1 从生活逻辑
┏ 类 ┓ ┏ 对象 ┓
┃ 人 ┃ 乔布斯 库克
┃ 电脑 ┃ 你桌子上那台 我桌子上这台
类class(不占用内存) 一个类的实例 instance(占内存)
1.2.2从封装角度
结构体:自定义的数据类型,封装成员变量,属性
函数:模块,封装子过程,方法
类:属性和方法的结合,同时封装了属性和方法(行为)
1.2.3从语言角度
类:类型
对象:变量,可读可写容器;常量,只读不写的容器;
1.2.4 从官方定义
类:一种数据抽象
对象:一种数据具象
2.OC语言与C语言的联系
2.1文件后缀名
c语言
oc 语言:*.m
2.2#import的作用
相当于#include,但比#include 更加智能,能避免头文件重复包含
-》 NSLog函数和printf函数的区别
自动换行
有时间戳前缀
2.3OC的字符串和 C 语言字符串的区别
@符号开始的字符串是 OC 的;
无@符号前缀的则为 C 的;
OC 字符串的代表符号是%@;
C 字符串的代表符号底%s;
OC字符串是一个对象;空间在堆区
C 语言字符串只是数据;空间在栈区
eg.oc语言简单使用(输出语句)
//相当于#include,但比其更加智能,避免头文件的重复包含 #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { //oc语言的关键词以@符号开头,@符号读作at for @autoreleasepool { NSString* myName = @"hello!"; //NSLog的输出,在程序的后台,对应于前台,在 iOS 中 UI界面是前台,Command Line Interface是后台 NSLog(@"Hello, World!"); NSLog(@"Hello, %@,%@.",myName,@"张三"); NSLog(@"Hello, %s.","hello"); } return 0; }
eg.oc语言创建一个类(方式一)
#import <Foundation/Foundation.h> //类的声明 @interface Person : NSObject{ NSString* nsName; //char* name; int age; } //'-'号开始的方法是实例方法; //'+'号开始的方法是类方法 - (void)setAge:(int)_age; @end //类的实现 @implementation Person - (void)setAge:(int)_age { age = _age; } @end int main(int argc, const char * argv[]) { @autoreleasepool { //类的使用 Person* person = [[Person alloc] init]; [person setAge:20]; } return 0; }
eg.oc语言创建一个类(方式二)
(1)头文件Person.h
//类的声明文件,类的接口文件 #import <Foundation/Foundation.h> @interface Person : NSObject { //@public//公开的,访问权限最大//所有的对象都能访问该属性 //类的属性//要用大括号括起来 int _number;//保存学号信息 //@protected//保护的,访问权限中庸//只有自己和子类能访问该属性 NSString* _name;//下划线开始的变量名作为类的属性变量,和形式参数相区别,这是工程习惯,代表该变量是对象内部的空间 //@private//私有的,访问权限最小//只有自己能访问该属性 int _age; } //中缀函数名方式 //id 相当于void* //id是泛型的对象指针类型 - (id)initWithNumber:(int)aNumber andName:(NSString*)aName andAge:(int)aAge; //类的方法//不能用大括号 - (void)setNumber:(int)aNumber; - (int)number; - (void)setAge:(int)aAge; - (int)age; - (void)setName:(NSString*)aName; - (NSString*)name; @end
(2)实现文件Person.m
//需要包含头文件 #import "Person.h" @implementation Person - (id)initWithNumber:(int)aNumber andName:(NSString*)aName andAge:(int)aAge { //super代表父类 //父类在帮对象初始化共同的继承的变量 if (self = [super init]) {//nil表示空对象 //对象初始化自己特殊的变量 _number = aNumber; _name = aName; _age = aAge; } //self是一个指向对象自己的对象指针,该指针由 NSObject 提供 return self; } //对象的自描述方法,也是一个由 NSObject 遗传的隐式方法, //我们可以按照自己的意愿,重写该方法(也即覆盖父类方法) - (NSString *)description{ return [NSString stringWithFormat:@"学号:%d,姓名:%@,年龄:%d",_number,_name,_age]; } - (void)setNumber:(int)aNumber{ //工程健壮性规范,加快运行时的效率 // if (_number != aNumber) { // _number = aNumber; // } //对于非对象属性,检查可选 _number = aNumber; } - (int)number{ return _number; } - (void)setName:(NSString*)aName{ //针对对象类型的属性,在设置值之前,必须检查是否为同一对象(指针) if(_name != aName){ _name = aName; } } - (NSString*)name{ return _name; } //setter方法,用于写入对象内部的属性数据 - (void)setAge:(int)aAge{ //设置对象内部的属性值 _age = aAge; } //getter方法,用于读取对象内部的属性数据 - (int)age{ //返回对象内部的属性值 return _age; } @end
(3)main.m文件
#import <Foundation/Foundation.h> //导入类的头文件 #import "Person.h" int main(int argc, const char * argv[]) { @autoreleasepool { //用类作为模板来创建对象 //对象的数据类型是指针类型,并且它是指向堆空间的指针类型 //OC中,所有对象,都用指针来引用 Person * xiaoLi = [[Person alloc] initWithNumber:20 andName:@"小李" andAge:28]; //NSLog(@"xiaoLi对象的自描述信息为:%@",[xiaoLi description]); NSLog(@"xiaoLi对象的自描述信息为:%@",xiaoLi); //写入 xiaoLi的属性信息 //在 OC中必须通过方法,对对象属性进行操作,以便保护对象的封装性 //[xiaoLi setName:@"小李"]; //方法调用,又称为发送消息,对象接受消息 // [xiaoLi setAge:28]; // [xiaoLi setNumber:13]; //[xiaoLi initWithNumber:20 andName:@"小李" andAge:18]; NSLog(@"xiaoLi name:%@",[xiaoLi name]); NSLog(@"xiaoLi age:%d",[xiaoLi age]); NSLog(@"xiaoLi number:%d",[xiaoLi number]); Person* p=[[Person alloc] init]; [p setNumber:22]; [p setName:@"哈哈"]; [p setAge:24]; NSLog(@"姓名:%@ 学号:%d 年龄:%d",[p name],[p number],[p age]); } return 0; }