---------------------- Java培训、.Net培训、Android培训、IOS培训、期待与您交流! ----------------------
注: 以下代码均为了省事,没有加入内存管理代码
之前已经了解了面向对象的思想了,在OOP中我们关注的重点是对象,那么接下来我们如何来得到我们想要的对象呢?日常生活中,以汽车为例,如果想得到一辆汽车首先要得到该汽车的设计图纸,然后根据图纸来 制造生产汽车,在编程中类相当于设计图纸,编译器相当于生产类的工厂,有了图纸有了工厂我们可以生产成千上万个类来使用。
/***************** car.h *****************/ #import <Foundation/Foundation.h> // 如果要使用OC面向对象的特性必须依赖于该框架 // 类的声明 @interface Car : NSObject // @interface是告诉编译器这是类的声明的开始 { // : NSObject 声明该类继承与NSObject,NSObject是所有对象的根类它具备对象的实例化能力 @public // @public 说明属相的访问权限为公有,就是可以通过指针来直接访问变量 // @protected 如果不写则默认为 @protected 对于子类公开,就是子类方法中可以访问父类的属性 // @package 只要处在同一个框架中,就能直接访问对象的成员变量 // @private : 只能在当前类的对象方法中直接访问(@implementation中默认是@private) int _wheels; // 多少个轮子 int _speed; // 时速 } - (void)run; // 跑的行为 @end // @end是告诉编译器类声明完毕 /***************** car.m *****************/ #import "car.h" // 类的实现 @implementation Car // @implementation告诉编译器类的实现开始 - (void) run { NSLog(@"%i个轮子,%i时速的车子跑起来了", _wheels, _speed); } @end // @end类的实现结束 /***************** main.h *****************/ #import "car.h" int main(){ Car *c = [Car new]; c->_wheels = 4; c->_speed = 150; [c run]; // 4个轮子,150时速的车子跑起来了 return 0; }
(1) 我们知道在C语言中函数一般我们提供函数的声明和实现,如果要调用该函数需要include该函数的头文件。
(2) 在类中的@interface相当于函数的声明,用来告诉调用者该类的总体结构,和提供哪些功能。
(3) 在@implementation中我们一般会把类的一些方法实现,一般这些细节的东西都不会对外公开的。
(4) @interface 相当于一个产品的框架 ,@implementation相当于把该框架填充,可以用一下图来形象的表示(该图引自苹果官方文档)
(5) 这样做的好处 :
1) 维护性好,如果某天要更改需求需要改变类的某个方法的实现,我们只需要更改该类的实现部分即可。
2) 有利于版本升级,对于@implementation文件我们可以随着版本的升级提供不同版本的文件
3) 清晰明了,调用者如果想快速了解该类只需要快速浏览该类的@interface文件,如果把声明跟实现写在同一个文件中将增加读取该类的难度。
(1) 属性命名要尽量有意义,而且尽量使用英文名词单词,对于复合单词用驼峰标识
(2) 属性命名以下划线 _ 开头,在OC中一般以下划线来标识类的属性
(3) 为了更好的可读性一般在属性定义后面加上注解(可选)。
(1) setter : - (void) set属性名(首字母大写去掉下划线):(属性类型)形参名称 ;
(2) getter : - (属性类型) 属性名称(去掉下划线) ;
// car.h #import <Foundation/Foundation.h> @interface Car : NSObject { // 属性要写在大括号内 int _wheels; // 多少个轮子 int _speed; // 时速 } - (void) setWheel:(int) wheel; - (int) wheel; - (void) setSpeed:(int) speed; - (int) speed;
(1) - 代表对象方法 , + 代表类方法。对象方法调用依赖于类,类方法依赖于类
(2) 声明和使用:
// Car.h #import <Foundation/Foundation.h> #import "Person.h" @interface Car : NSObject { // 属性要写在大括号内 int _wheels; // 多少个轮子 int _speed; // 时速 } - (void) setWheel:(int) wheel; - (int) wheel; - (void) setSpeed:(int) speed; - (int) speed; // 一个人启动一辆车 - (BOOL) startBy: (Person *) person; // - 对象方法; (BOOL) 返回值类型 ; startBy: 方法名 ; (Person *) 参数类型 ; person 参数名称 + (void) introduce; // + 类方法 // Car.m ... // main.m #import "Car.h" #import "Person.h" int main(){ [Car introduce]; // 调用类方法 Car *c = [Car new]; // 对象的创建 Person *p = [Person new]; BOOL b = [c startBy: p]; // 对象方法调用 NSLog("start %@"( b ? @"success" : @"failed")); return 0; }
(1) 成员变量不能在{}中进行初始化、不能被直接拿出去访问
(2) 方法不能当做函数一样调用
(3) 成员变量\方法不能用static等关键字修饰,别跟C语言混在一起(暂时忽略)
(4) 类的实现可用写在main函数的后面,主要在声明后面就行了
(1) OC方法只能声明在@interface和@end之间,只能实现在@implementation和@end之间。也就是说OC方法不能独立于类存在
(2) C函数不属于类,跟类没有联系,C函数只归定义函数的文件所有
(3) C函数不能访问OC对象的成员
(4) 低级错误:方法有声明,但是实现的时候写成了函数
(5) 方法只有声明,没有实现(经典错误)
(6) 方法没有声明,只有实现(编译器警告,但是能调用,OC的弱语法)
(7) 编译的时候:访问没有的成员变量直接报错,访问没有的方法,只是警告
在 java 和 C++ 中有 this 指针指向当前对象,因此我们可以通过 this 指针来访问该对象的成员变量和方法,一般该指针只限制于该对象的内部使用。OC 提供了self 关键字那么该关键字与this指针是否有相同的作用 呢?答案是否,该关键字指向的是调用者本身,那么该关键字可以用于对象方法(类似于java中的静态方法)中,但在 java 中this指针不能用于静态方法。
// Number.h #import <Foundation/Foundation.h> @interface Number: NSObject { int _value; } - (void) setValue:(int)value; - (int) value; - (int) addWith:(Number *)num; + (int) num1:(Number *)n1 addWith:(Number *)n2; + (void) printAddResultWith:(Number *)n1 and:(Number *)n2; @end // Number.m #import "Number.h" @implementation Number - (void) setValue:(int)value { self -> _value = value; // 在对象方法中self指向当前对象,因此可以通过该指针来访问成员变量 // [self setValue:value]; // 在某个方法中不能使用self调用该方法否则会引发死循环 } - (int) value { return _value; } - (int) addWith:(Number *)num { return [self value] + [num value]; // 在对象方法中self指向当前对象,分别通过self指针访问成员变量 和 通过对象访问成员变量 } + (int) num1:(Number *)n1 addWith:(Number *)n2 { return [n1 value] + [n2 value]; } + (void) printAddResultWith:(Number *)n1 and:(Number *)n2 { NSLog(@"the result is: %d"[self num1:n1 addWith:n2]); // 在类方法中self指向当前类对象,因此它可以调用该类对象的类方法 } @end
同样在java中也有super关键字,不过要注意区分的地方跟 self 和 java中的this一样,super指向的是调用者父类的相应对象:
对象方法 中 super 指向 的 父类对象 ,因此我们可以通过super关键字调用父类中的相应对象方法。
类方法 中 super指向的是 父类的类对象 ,因此我们可以通过super关键字调用父类中相应的类方法。
/* Person.h */ #import <Foundation/Foundation.h> @interface Person: NSObject { int _age; } - (void) setAge:(int)age; - (int)age; + (id) initWithAge:(int)age; // 声明一个构造方法返回一个OC对象的万能指针 + (void) ageDesciption(Person *)p; @end /* Person.m */ #import "Person.h" @implementation Person - (void) setAge:(int)age { self->_age = age; } - (int)age { return _age; } + (id) initWithAge:(int)age // 构造方法实现 { id p = [[Person alloc] init]; [p setAge:age]; return p; } + (void) ageDesciption(Person *)p { if ( [p age] < 18 ) { NSLog("青少年一个"); } else { NSLog("非青少年"); } } @end /* Student.h */ #import "Person.h" @interface Student : Person // Student继承与Person类将拥有父类的属性和方法 { NSString *_name; } - (void) setName:(NSString *)name; - (NSString *)name; + (id) initWithName:(NSString *)name andAge:(int)age; // 声明一个构造方法 + (void) introduceHimself; @end /* Student.m */ #import "Student.h" @implementation Student - (void) setName:(NSString *)name { _name = name; } - (NSString *)name { return _name; } + (id) initWithName:(NSString *)name andAge:(int)age // 构造方法实现 { id s = [super age]; // super当前指向Student类对象的父类对象 [s setNmae:name]; return id; } - (void) introduceHimself { int age = [super age]; // super指向当前对象的父类对象 NSLog("my name is %@, age is %d",_name,_age); } @end /* main.m */ #import "Student.h" int main(){ Student *s = [Student initWithName:@"jack" andAge:20]; [s introduceHimself]; return 0; }
---------------------- Java培训、.Net培训、Android培训、IOS培训、期待与您交流! ----------------------
详情请查看:http://edu.csdn.net/heima