标签:
1.oc简介
C语言的基础上,增加了一层最小的面向对象语法
完全兼容C语言
可以在OC代码中混入C语言代码,甚至是C++代码
可以使用OC开发Mac OS X平台和iOS平台的应用程序
2.oc语法
关键字
@interface类的声明、@implementation类的实现、@end结束
@public公有、@protected保护、@private私有、@selector
@try、@catch、@throw、@finally
@protocol、@optional、@required、@class
@property、@synthesize、@dynamic
self、super、id、_cmd、__block、__strong、__weak、
字符串以@开头 比如@"Hello"为oc的字符串 c的字符串"Hello"
oc程序的开发过程:
和c程序的开发过程类似
源程序.m 经过编译 生成目标文件.o 再经过链接 生成可执行文件a.out
编译cc –c main.m
链接cc main.o –framework Foundation
注意:oc程序的链接,只是把c的库函数自动链接,而oc自己的库函数,需要链接的时候写上:
–framework Foundation,只要用了foundation框架,就得写。
(这边你可以理解为增加 -framework Foundation 是因为该程序中使用了Foundation的框架中头文件,可以方便快速寻找该头文件)
编译、链接生成文件的自定义命名:
一般的编译处理,如何对编译、链接生成的目标文件、可执行文件进行重命名,主要是在对其后增加-o XXX,便重命名成为XXX
oc程序开发的编译链接的重命名如下:
编译cc -c main.m -o abc //其义为生成abc的目标文件
链接cc abc -framework Foundation -o def //其义为生成def的可执行文件
下面为汇编和gcc 的编译链接的文件重命名
1) 预处理
gcc -E test.c -o test.i
在当前目录下会多出一个预处理结果文件 test.i,打开 test.i 可以看到,在 test.c 的基础上把stdio.h和stdlib.h的内容插进去了。
2) 编译为汇编代码
gcc -S test.i -o test.s
其中-S参数是在编译完成后退出,-o为指定文件名。
3) 汇编为目标文件
gcc -c test.s -o test.o
.o就是目标文件。目标文件与可执行文件类似,都是机器能够识别的可执行代码,但是由于还没有链接,结构会稍有不同。
3) 链接并生成可执行文件
gcc test.o -o test
如果有多个源文件,可以这样来编译:
gcc -c test1.c -o test1.o
gcc -c test2.c -o test2.o
gcc test1.o test2.o -o test
注意:如果不指定文件名,GCC会生成名为a.out的文件,.out文件只是为了区分编译后的文件,Linux下并没有标准的可执行文件后缀名,一般可执行文件都没有后缀名。
编辑,编译,链接(把所有的相互关联的.o文件合并在一起,加上函数库),运行。和c类似,先编写.m文件,然后编译器编译,链接,运行。
跟C语言一样,OC(objective-c)程序的入口依然是main函数,只不过写到一个.m文件中(文件名可以是中文)。
1 #include <stdio.h>
2
3 //oc程序的入口函数也是main函数
4
5 int main(void)
6
7 {
8
9 printf("第一个oc程序!oc源文件完全兼容c语言!");
10
11 return 0;
12
13 }
编译cc –c main.m,链接cc main.o,运行./a.out
1 #import <Foundation/NSObjCRuntime.h>
2 //不是#include,而是#import
3 int main(void)
4 {
5 //NSlog输出内容自动换行
6 NSLog(@"第二个oc程序!!");
7 return 0;
8 }
编译cc –c main.m
链接cc main.o –framework Foundation
注意:oc程序的链接,只是把c的库函数自动链接,而oc自己的库函数,需要链接的时候写上:–framework Foundation,只要用了foundation框架,就得写。
运行./a.out
NSLog接收OC字符串作为参数,printf接收C语言字符串作为参数
NSLog输出后会自动换行,printf输出后不会自动换行
使用NSLog需要#import <Foundation/Foundation.h>,里面有NSLog函数的声明。
Foundation框架下的NSObjCRuntime.h头文件
不需要刻意记忆,想不起来,就编译,出错就会提示缺少什么。
可以只包含框架的主头文件,效果等价包含了这个框架里的所有的头文件。头文件在Xcode里面,路径很深,不好找。
使用printf需要#include <stdio.h>
1、跟#include一样,用来拷贝某个文件的内容
2、可以自动防止文件内容被拷贝多次,也就是头文件中不用和C一样,加入下面的预处理指令了
#ifndef xxx xxx
#define xxx xxx
#endif
开发iOS、Mac程序必备的框架,此框架中包含了很多常用的API(应用编程接口)。框架中包含了很多头文件,若想使用整个框架的内容,包含它的主头文件即可
#import <Foundation/Foundation.h>
BOOL类型的本质:typedef signed char BOOL;
BOOL类型的变量只有两种取值:YES、NO
#define YES (BOOL)1
#define NO (BOOL)0
BOOL的输出(当做整数来用);NSLog(@"%d %d", YES, NO);//1 0
C里没有布尔类型,c++里有,oc也有。不过oc的布尔和c++有区别,在C++里一切非 0 值的东西都为 true,而为0值的为false。但是Object-c里必须是1为 true ,且并被宏定义为 YES,0 为 false 并被宏定义为 NO。所以下面的代码,则肯定是得不到想要的运行顺序。
1 #import <Foundation/Foundation.h>
2 BOOL isBool(int, int);
3
4 int main(void)
5 {
6 if (isBool(5, 1) == YES) {
7 NSLog(@"ok");
8 }
9 return 0;
10 }
11 BOOL isBool(int x, int y)
12 {
13 return x - y;
14 }
4不是1,在oc里永远都不会等于YES(YES就是1),注意:BOOL大写,YES NO也是大写,YES就是1,NO就是0
跟C语言中多文件的开发是一样的,回忆c多文件开发,常量的定义或者函数的声明写在xxx.h文件,函数的定义写在xxx.c文件,主文件main.c里写主程序和函数调用,最后#include xxx.h文件,一起编译主文件main.c和xxx.c文件即可。
编写3个oc文件
main.m
#import "one.h"
int main()
{
test();
return 0;
}
one.h
void test();
one.m
#import <Foundation/Foundation.h>
void test()
{
NSLog(@"调用了test函数");
}
编译:cc –c main.m test.m (两个文件要一起编译)
链接:cc main.o test.o –framework Foundation
运行:./a.out
main.m
#import "one.h"
int main()
{
test();
return 0;
}
one.h
void test();
one.c
#include <stdio.h>
void test()
{
printf("调用了test函数\n");
}
编译:cc –c main.m one.c
链接:cc main.o test.o (没有使用Foundation框架的话,就不用-framework Foundation)
运行:./a.out
面向对象的思想和面向过程的思想:
OC是面向对象的,C是面向过程的。面向对象和面向过程只是解决问题的两种不同思想
1) 以用电脑听歌为例子
a) 面向过程
b) 面向对象(不是相亲的“对象”)
² 开机
² 播放歌曲
² 关机
2) 区别分析
面向对象中有2个非常重要的概念:类和对象
1) 面向对象解决问题的时候必须有对象,那如何创建对象呢?
2) 现实生活的例子:如何创造汽车对象?
a) 需要先有汽车的建造图纸,图纸上描述清楚汽车应该具备的属性和功能(行为)
b) 然后再根据图纸上的描述生成汽车
c) 每一辆汽车都是对象,都有自己具体的属性值,都是图纸的实例
d) 图纸是抽象的,房子是具体的。图纸是对房子对象的高度概括
1) OC中的类相当于图纸,用来描述一类事物。也就是说,要想创建对象,必须先有类
2) OC利用类来创建对象,对象是类的具体存在
3) 因此,面向对象解决问题应该是先考虑需要设计哪些类,再利用类创建多少个对象
1) 类的设计,只关心3样东西:
2) 一般名词都是类
3) 拥有相同(或者类似)属性和行为的对象都可以抽像出一个类
1. 愤怒的小鸟游戏界面
2. 植物大战僵尸
3. 新浪微博
4) 类名、属性、行为练习
5) 哪个对象最清楚这个行为,就把这个行为写到哪个对象中去。打开电脑(开机)这个行为应该是属于电脑的。
1) 代码编写
#import <Foundation/Foundation.h>
// 类的声明
@interface Car : NSObject
{
@public
int wheels; // 多少个轮子
int speed; // 时速
}
- (void)run; // 跑的行为
@end
2) 成员变量
3) @public
@public可以让Car对象的wheels和speed属性被外界访问
4) NSObject
加上:NSObject的目的是让Car类具备创建对象的能力
// 类的实现
@implementation Car
- (void) run
{
NSLog(@"%i个轮子,%i时速的车子跑起来了", wheels, speed);
}
@end
1) 代码编写
// 主函数
int main()
{
// 创建车子对象
Car *c = [Car new];
c->wheels = 3;
c->speed = 300;
[c run];
return 0;
}
2) main函数的代码分析、内存分析(对象在内存中有成员)
Car *c = [Car new];
用一个指针变量c指向内存中的Car对象
跟用指向结构体的指针访问结构体属性一样,用->
c->wheels = 3;
c->speed = 300;
Car *c1 = [Car new];
c1->wheels = 4;
Car *c2 = [Car new];
c2->speed = 250;
[c1 run];
Car *c1 = [Car new];
c1->wheels = 4;
c1->speed = 250;
Car *c2 = c1;
c2->wheels = 3;
[c1 run];
u 修改指向指向对象的成员
u 修改指针的指向
u @interface就好像暴露在外面的时钟表面
u @implementation就好像隐藏在时钟内部的构造实现
l 只有类的声明,没有类的实现
l 漏了@end
l @interface和@implementation嵌套
l 两个类的声明嵌套
l 成员变量没有写在括号里面
l 方法的声明写在了大括号里面
l 成员变量不能在{}中进行初始化、不能被直接拿出去访问
l 方法不能当做函数一样调用
l 成员变量\方法不能用static等关键字修饰,别跟C语言混在一起(暂时忽略)
l 类的实现可用写在main函数的后面,主要在声明后面就行了
l OC方法只能声明在@interface和@end之间,只能实现在@implementation和@end之间。也就是说OC方法不能独立于类存在
l C函数不属于类,跟类没有联系,C函数只归定义函数的文件所有
l C函数不能访问OC对象的成员
l 方法只有声明,没有实现(经典错误)
l 方法没有声明,只有实现(编译器警告,但是能调用,OC的弱语法)
l 编译的时候:访问没有的成员变量直接报错,访问没有的方法,只是警告
@implementation Car : NSObject
{
@public
int wheels; // 多少个轮子
int speed; // 时速
}
- (void) run
{
NSLog(@"%i个轮子,%i时速的车子跑起来了", wheels, speed);
}
@end
设计一个Caculator计算器类,它拥有计算的功能(行为)
u 设计一个返回PI的方法
// 方法声明
- (double)pi;
// 方法实现
- (double)pi
{
return 3.14;
}
u 方法调用
u 设计一个计算平方的方法
// 方法声明
- (double)square:(double)number;
// 方法实现
- (double)square:(double)number
{
return number * number;
}
u 方法调用
u 设计一个计算和的方法
// 方法声明
- (double)sumOfNum1:(double)num1 andNum2:(double)num2;
// 方法实现
- (double)sumOfNum1:(double)num1 andNum2:(double)num2
{
return num1 + num2;
}
u 方法调用
l 冒号也是方法名的一部分
l 同一个类中不允许两个对象方法同名
给Car类设计一个方法,用来和其他车比较车速,如果本车速度快,就返回1,如果本车速度慢,就返回-1,速度相同就返回0
l 属性访问
[Car new]->speed = 200;
l 方法调用
[ [Car new] run];
@public的成员可以被随意赋值,应该使用set方法和get方法来管理成员的访问(类似机场的安检、水龙头过滤,过滤掉不合理的东西),比如僵尸的生命值不能为负数
1) 作用:用来设置成员变量,可以在方法里面过滤掉一些不合理的值
2) 命名规范:
1) 作用:返回对象内部的成员变量
2) 命名规范:get方法的名称一般就跟成员变量同名
#import <Foundation/Foundation.h>
// 声明
@interface Car : NSObject
{
int _wheels; // 轮子个数
}
/*set方法*/
- (void) setWheels:(int)wheels;
/*get方法*/
- (int) wheels;
@end
@implementation Car
// set方法的实现
- (void) setWheels:(int)wheels
{
// 对外面传进来的轮子数进行过滤
if (wheels<=0)
{
wheels = 1;
}
_wheels = wheels;
}
// get方法的实现
- (int) wheels
{
return _wheels;
}
@end
1> Dog类,属性:weight、speed,方法:吃、跑
2> Person类,属性:dog、age,方法:喂狗、遛狗
直接可以用类名来执行的方法(类本身会在内存中占据存储空间,里面有类\对象方法列表)
1) 对象方法
2) 类方法
3) 类方法和对象方法可以同名
1) 出现的地方:所有的OC方法中(对象方法\类方法),不能出现在函数
2) 作用
黑马程序员-oc基础---oc简介、语法、思想 Foundation框架 编译链接文件的重命名 类方法 set get self
标签:
原文地址:http://www.cnblogs.com/cheng923181/p/4492447.html