---------------------- Java培训、.Net培训、Android培训、IOS培训、期待与您交流! ----------------------
注: 以下代码均为了省事,没有加入内存管理代码
1. 类
之前已经了解了面向对象的思想了,在OOP中我们关注的重点是对象,那么接下来我们如何来得到我们想要的对象呢?日常生活中,以汽车为例,如果想得到一辆汽车首先要得到该汽车的设计图纸,然后根据图纸来 制造生产汽车,在编程中类相当于设计图纸,编译器相当于生产类的工厂,有了图纸有了工厂我们可以生产成千上万个类来使用。
2. 类的声明和实现
/***************** 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;
}
3. @interface和@implementation 的分工和好处
(1) 我们知道在C语言中函数一般我们提供函数的声明和实现,如果要调用该函数需要include该函数的头文件。
(2) 在类中的@interface相当于函数的声明,用来告诉调用者该类的总体结构,和提供哪些功能。
(3) 在@implementation中我们一般会把类的一些方法实现,一般这些细节的东西都不会对外公开的。
(4) @interface 相当于一个产品的框架 ,@implementation相当于把该框架填充,可以用一下图来形象的表示(该图引自苹果官方文档)
(5) 这样做的好处 :
1) 维护性好,如果某天要更改需求需要改变类的某个方法的实现,我们只需要更改该类的实现部分即可。
2) 有利于版本升级,对于@implementation文件我们可以随着版本的升级提供不同版本的文件
3) 清晰明了,调用者如果想快速了解该类只需要快速浏览该类的@interface文件,如果把声明跟实现写在同一个文件中将增加读取该类的难度。
4. 类编写的一些规范
a. 属性命名规范
(1) 属性命名要尽量有意义,而且尽量使用英文名词单词,对于复合单词用驼峰标识
(2) 属性命名以下划线 _ 开头,在OC中一般以下划线来标识类的属性
(3) 为了更好的可读性一般在属性定义后面加上注解(可选)。
b. 属性的 settter 和 getter
(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;
c. 方法的命名规范
(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;
}
5. 一些注意地方
a. 语法方面注意点
(1) 成员变量不能在{}中进行初始化、不能被直接拿出去访问
(2) 方法不能当做函数一样调用
(3) 成员变量\方法不能用static等关键字修饰,别跟C语言混在一起(暂时忽略)
(4) 类的实现可用写在main函数的后面,主要在声明后面就行了
b. 方法注意点
(1) OC方法只能声明在@interface和@end之间,只能实现在@implementation和@end之间。也就是说OC方法不能独立于类存在
(2) C函数不属于类,跟类没有联系,C函数只归定义函数的文件所有
(3) C函数不能访问OC对象的成员
(4) 低级错误:方法有声明,但是实现的时候写成了函数
(5) 方法只有声明,没有实现(经典错误)
(6) 方法没有声明,只有实现(编译器警告,但是能调用,OC的弱语法)
(7) 编译的时候:访问没有的成员变量直接报错,访问没有的方法,只是警告
6. self 关键字
a. self 初步认识
在 java 和 C++ 中有 this 指针指向当前对象,因此我们可以通过 this 指针来访问该对象的成员变量和方法,一般该指针只限制于该对象的内部使用。OC 提供了self 关键字那么该关键字与this指针是否有相同的作用 呢?答案是否,该关键字指向的是调用者本身,那么该关键字可以用于对象方法(类似于java中的静态方法)中,但在 java 中this指针不能用于静态方法。
b. 如何使用
// 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
7. super关键字
a. super初步认识
同样在java中也有super关键字,不过要注意区分的地方跟 self 和 java中的this一样,super指向的是调用者父类的相应对象:
对象方法 中 super 指向 的 父类对象 ,因此我们可以通过super关键字调用父类中的相应对象方法。
类方法 中 super指向的是 父类的类对象 ,因此我们可以通过super关键字调用父类中相应的类方法。
b. 如何使用
/*
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