01-基本语法、类和对象
2017-09-09 本文已影响0人
SnorlaxSE
一、基本语法
1、Objectiv-C简介:
a、是C语言的基础上,增加了一层最小的面向对象语法;
b、完全兼容C语言;
c、可以在OC代码中混入C语言代码,甚至是C++代码;
d、扩展名是:.m,想写入c++代码,扩展名改成 .mm;
2、关键字:
基本上所有关键字都是以@开头;例如:@interface,@implementation,@end,@public等
3、字符串:
字符串以@开头 如:@”hello”;而"hello"是C语言字符串。
4、基本数据类型:char、int、float、double、BOOL(YES/NO);
BOOL类型的本质:typedef signed char BOOL;
有两种取值: YES/NO;
`#define YES (BOOL)1`
`#define NO (BOOL)0
BOOL的输出:当整数来用 %d/%i;
5、nil相当于C语言中的NULL,也就是0;
6、输出语句:
NSLog(@"hello"); NSLog(@"hello,%d",15);//输出内容后会自动换行
NSLog的用法与printf区别:
a、NSLog是Foundation框架下的东西,使用需要#import <Foundation/Foundation.h>;使用printf需要 #include<stdio.h>
b、NSLog输出时会自动换行,printf不会。
c、NSLog输出时写法@"xxxxx",参数需要的是NSString类型,而printf需要的是char* 类型的数据
d、OC中的字符串如果想打印用NSLog的%@,printf不能使用%@进行输出的
e、NSLog的时间初是不能去掉的
7、基本语句:
循环语句(do while、while、for)、条件语句(if、if-else、switch)
8、注释:“//”和“/....../”
9、 开发过程和C语言类似:.m源文件->编译->.o目标文件->链接->可执行文件
a、加载Foundation框架的所有内容#import <Foundation/Foundation.h>
b、#import用途:
(1)、跟include一样,拷贝文件的内容;
(2)、可以防止文件的内容被重复拷贝;
c、编译-链接-运行
编译:cc –c 文件名.c;
链接:cc 文件名.o –framework Foundation
运行:./a.out
d、主头文件:
(1)、最主要的头文件,名字一般跟框架名称一样,包含了框架中的所有其他头文件;
(2)、Foundation框架的主头文件名称就是Foundation.h;
(3)、只需要包含Foundation框架的主头文件,就可以使用整个框架的东西;
10、代码简单编写:第一个OC程序
#import <Foundation/Foundation.h>
int main()
{
NSLog(@"第一个OC程序");
return 0;
}
跟C语言一样,OC程序的入口依然是main函数,只不过写到一个.m文件中
二、类和对象
1、OC是面向对象的,C是面向过程的
区别分析:面向过程关注的是解决问题需要哪些步骤;面向对象关注的是解决问题需要哪些对象;两种思想都能达到解决问题的目的,但是解决思路不一样;
2、类和对象的关系:
类是对所有对象相同属性的概括,就是对象的描述。
a、面向对象开发步骤:首先考虑需要设计哪些类,再利用类创建多少个对象
(1)、设计类的步骤:类的名称(有意义的类名),属性,行为;
(2)、一般的名词都是类,类名的第一个字母必须是大写的,不能有下划线,多个英文单词,用驼峰标识(每个英文单词首字母大写);
(3)、拥有相同(或类似)属性和行为的对象都可以抽象出一个类;
(4)、哪个对象最清楚这个行为,就把这个行为写到哪个对象中去;
3、创建一个OC类:
完整地写一个类:类的声明和类的实现;(完整地写一个函数:函数的声明和定义(实现))
类名:1>类名的第一个字母必须大写;2>不能有下划线;3>多个单词间用驼峰标识。例如JumpZoombie
a、类的声明
@interface 类名 : NSObject// :NSObject目的是让类具备创建对象的能力
{
成员变量(实例变量):数据类型 成员变量名;
}
方法声明 - (数据类型)方法;
@end
b、类的实现
@implementation 类名
方法的实现
- (数据类型)方法
{
}
@end
c、使用注意
(1)、类的方法实现的时候,方法内可直接访问成员变量
(2)、类在内存中也占据存储空间,从头到尾只占据一块存储空间;
(3)、第一次创建对象的时候,首先分配内存给类,然后在分配内存给创建的对象;
(4)、在使用类创建对象之前,会将类加载进内存(只有一次),类的内存里只存放方法列表;
(5)、定义的对象内部都有一个默认的isa指针,指向对象所对应的类;
(6)、[p run]; [消息接收者 消息]:是给指针p所指向的对象发送一条run消息,对象会顺着isa指针找到对应的类,去类里找run方法。
d、实例分析:
//目的:因为使用了NSObject
#import <Foundation/Foundation.h>
//1、类的声明
//声明对象的属性、行为
//NSObject 目的是:让Car这个类具备创建对象的能力
//OC对象本身是结构体
@interface Car : NSObject
{
//@public可以让外部的指针间接访问对象内部的成员变量
@public
//用来声明对象属性(成员变量,也叫实例变量,默认会初始化为0)
int wheels;//轮胎的个数
int speed;//时速(xxkm/h)
//实例变量不允许在这里初始化 int wheels = 4这种写法是错误的
//不能随便将成员变量当做C语言中的变量来使用 static int wheels;这种写法是错误的
}
//方法(行为): 方法名 、 参数 、返回值 (声明、实现)
//只要是OC对象的方法,必须以减号 - 开头
//OC方法中任何数据类型都必须用小括号()括住
//OC方法中的小括号()的作用只有一个:括住数据类型
- (void) run;
//类的声明完毕
@end
//2、类的实现
//用来实现interface中声明的方法
//方法的实现(说清楚方法里面有什么代码)
@implementation Car
- (void) run
{
//方法内可直接访问、调用成员变量
NSLog(@"%d个轮子、%d车速的车跑起来了",wheels,speed);
}
//类的实现完毕
@end
int main()
{
//在使用类创建对象之前,会将类加载进内存(只有一次),类的内存里只存放方法列表
//定义的对象内部都有一个默认的isa指针,指向对象所对应的类
//OC中,想执行一些行为,就写上一个中括号[行为执行者,行为名称]
//利用类来创建对象
//执行了Car这个类的new行为来创建新的对象
//OC中只能用指针变量来间接操作对象
//定义了一个指针变量p,p将来指向的是Car类型的对象
//[Car new]会创建出一个新对象,并且会返回新对象本身(新对象的地址)
Car *p = [Car new];
Car *p2 = [Car new]; //又创建出一个新对象p2
//给p所指向对象的wheels属性赋值4
p->wheels = 4;
p2->speed = 300;
//给p所指向对象发送一条run消息 (OC中的消息机制)
[p run];
[p2 run];
NSLog(@("p车有%d个轮胎,速度是%dkm/hnp2车有%d个轮胎,速度是%dkm/h"),p->wheels,p->speed,p2->wheels,p2->speed);
//将p里存储的地址值,赋值给了p3,两个指向的地址值是相同的,指向同一个对象
Car *p3 = p;
p3->speed = 200;
[p run];
[p3 run];
//将p2里存储的地址赋值给p
p = p2;
p->wheels = 3;
[p run];
[p2 run];
return 0;
}
4、对象跟函数参数
a、OC里的对象不能自动回收;
b、书写类和对象注意事项:
(1)不能嵌套包含;
(2)方法的实现不能写在@interface中;
(3)方法的声明不能写在@implementation中;
(4)方法的声明不能写在定义属性的大括号{}中,一定要写在外面
(5)类内不能写其他新的类,想写另一个类,应写在@interface 类名 : NSObject @end @implementation 类名 @end的外面;
(6)在函数内不能直接写对象的实例变量;
(7)实例变量不允许初始化赋值;
(8)不能随便将实例变量当做C语言中的变量(实例变量不能用 static 修饰);
(9)类的声明必须放在main函数前面,类的实现可以放在后面;
(10)@implementation没有@interface也可以创建对象
(11)@implementation中不能声明和@interface一样的成员变量
5、方法与函数的区别
a、方法
(1)、对象方法都是以减号 - 开头,变量类型用()括住
(2)、OC方法的声明必须写在@interface和@end之间,方法的实现必须写在@implementation和@end之间。也就是说OC方法不能独立于类存在
(3)、对象方法只能由对象来调用
(4)、对象方法归类对象所有
b、函数
(1)、函数能写在文件中的任意位置(@interface和@end之间除外),函数归文件所有
(2)、函数调用不依赖于对象
(3)、函数内部不能直接通过成员变量名访问某个对象的成员变量
成员变量可以是任意类型,也可以是其他对象
6、方法的声明和实现
a、OC方法中,一个参数对应一个冒号:;
b、冒号的作用:分隔方法调用时的参数值;
c、不带参数的方法`- (double)pi; 方法名为pi`
d、带一个参数的方法
- (int)square : (int)num; 方法名为square :(冒号也是方法名的一部分)
e、带多个参数的方法
- (int)sumWithNum1 : (int)num1 andNum2 : (int)num2;
(方法名为 sumWithNum1: andNUm2: )
f、同一个类中不允许两个对象方法同名
7、匿名对象(没有名字的对象)
@interface Car : NSObject
{
@public
int speed;
}
- (void) run;
@end
@implementation Car
- (void) run
{
NSLog(@"%d个轮子、%d车速的车跑起来了",wheels,speed);
}
@end
int main()
{
//属性访问
[Car new]->speed = 300;
//方法调用
//每次都会创建新的对象,所以speed的值是0
[[Car new] run];
return 0 ;
}
不要写类似匿名对象这样的代码!!!
对象调用类方法 内存分析示意图