您的位置:首页 > 其它

Ryan的OC学习总结-----2 OC中的面向对象特性

2016-06-23 15:00 579 查看
一 面向对象的基本特性

1 封装性。封装性就是尽可能隐藏对象的内部细节,对外形成一个边界,只保留有限的对外接口使之与外部发生联系。@implementation Song
.....
@end
2 继承性。一些特殊类能够具有一般类的全部属性和方法,这称作特殊类对一般类的继承。通常我们称一般类为父类或基类,称特殊类为子类或派生类

3 多态性。对象的多态性是指在父类中定义的属性或方法被子类继承之后,可以使同一个属性或方法在父类及其各个子类中具有不同的含义,这称为多态性。例如动物都有吃的方法,但老鼠和猫的吃法是截然不同的。

二 OC语言的面向对象

1 OC的类

接口部分:使用关键字@interface,主要指定类名 继承的父类 实现的协议 成员变量和方法等信息。

@interface Song:NSObject{//NSObject是有所对象根类
....
}
....
@end示例:
@interface Song: NSOblect{
NSString *title;
NSString *artist;
long int duartion;
}
- (void) start;
- (void) stop;
- (void) seek:(long int) time;
@end

实现部分:使用@implementation,主要实现了在接口部分定义的方法等信息。
@implementation Song

- (void) start{
//开始播放
}
- (void) stop{
//停止播放
}
- (void) seek:(long int)time{
//跳过时间
}
@end

2 消息传递机制
OC最大的特色是承自Smalltalk的消息传递模型(message passing)。在OC里是对象之间相互传递消息

在OC中类与消息的关系比较松散,调用方法视为对对象发送消息,所有方法都被视为对消息的回应
//C++里调用obj对象method方法语法如下
obj.method(argument)
//OC里向obj对象发送method:消息语法如下
[obj method: argument]
3 OC多重参数

OC中方法定义非常古怪,它遵循了Smalltalk语法风格,将一个方法名字分成几个部分

3 成员变量封装

OC作为一种面向对象的语言,为了实现封装性,OC提供变量作用域访问限定指令(@public @private @protected@package)。如果一个实例变量没有任何的作用域限定的话,那么缺省就是@protected

作用域访问限定只能限定成员(实例)变量,不能限定方法

OC可以直接通过对象访问成员变量的,访问操作符是"->",例如song->title

4 作用域访问限定指令

@public:可以在任何情况下访问

@private:只能在这个类里面才可以访问

@protected:可以在这个类里面和这个类的派生子类里面访问这个变量,在类外的访问时不推荐的

@package:只能在这个类所在的库或者框架内部访问等同@public;如果在库或者框架外部访问等同@private。@package只能应用于现代
64位运行库,如果是老的32位运行库,其含义与@public形同。@interface Song: NSOblect{
@public
NSString *title;
NSString *artist;
@private
long int duartion;
}
5 通过getter和setter方法访问成员变量

面向对象的封装,不仅需要对类的成员变量限定访问,而且还要为类提供可以在外部能够访问的方法

为了访问成员变量而提供读取方法getter和设定方法setter。不要直接访问成员变量

@implementation Song
.....
- (NSString *)title{
return title;
}
- (void)setTiltle : (NSString *)newtitle{
title = newTitle;
}
......
@end6 属性
在定义和实现getter和setter方法时代码量会大而繁琐。为了简化这些琐碎编码,OC2.0提出属性的概念,使用@property指令在接口部分声明属性;在实现部分使用@synthesize指令再组装和合成这些属性。

@interface Song: NSOblect{
NSString *title;
NSString *artist;
long int duartion;
}
- (void) start;
- (void) stop;
- (void) seek:(long int) time;

@property(copy,readwrite) NSString *title;
@property(nonatomic,retain) NSString *artist;
@property(readonly) long int duration;

@end属性中的参数:
读写属性参数:readwrite readonly

管理内存参数: MRC内存管理相关的assign/retain/copy;ARC内存管理相关的strong weak等

线程安全参数:原子性atomicity和非原子性nonatomoc。atomictity是原子性的线程安全的,但会影响性能。如果确定不考虑线程安全问题可以使用nonatomic.

@implementation Song

@synthesize title;
@synthesize artist;
@dynamic duration;
.....
@end通过@synthesize指令编译器会在编译时候生成setter和getter方法。
7 构造函数
Song* song = [[Song alloc] init];
//alloc是分配内存空间,init是构造函数
Song *song = [Song new]; 对象在创建后,马上就应该初始化它的成员变量。
出于初始化类中的成员变量的需要,可以提供一个方法用于此目的,这个方法就叫构造函数或者构造方法(Constructor)。与Cpp和java不同,OC命名是没有限制的,并且有返回值本身类型指针。

构造函数的声明:(Song.h文件)

@interface Song: NSOblect{
NSString *title;
NSString *artist;
long int duartion;
}
........
//构造函数
- (Song *)initWithTitle:(NSString *)newTitle aandArtist:(NSString *)newArtist andDuration:(long int)newDuration;
//构造函数
- (Song *)init;
@end注:构造函数一般用init开头命名,它的返回值很特殊,是返回值本身类型指针,返回值或者对象指针泛型id,或instancetype关键字都可以。

构造函数的实现:
@implementation Song
........
//构造函数,指定构造函数
- (Song *)initWithTitle:(NSString *)newTitle aandArtist:(NSString *)newArt
4000
ist andDuration:(long int)newDuration{
self = [super init];
if (self){//(self != nil)
self.title = newTitle;
self.artist = newArtist;
self.duration = newDuration;
}
return self;
}
//构造函数,便利构造函数
- (Song *)init{
return [self initWithTitle:@"Sun" andArtist:@"Tom" andDuration:90];
}
.......
@end调用构造函数:
Song* song = [[Song alloc] initWithTitle:@"Sun" andArtist:@"Tony.Guan" andDuration:100];
NSLog(@"artist = %@", song.artist);
NSLog(@"duration = %li",song.duration);

8 类变量和类方法
有一个Account类(银行账户),假设它有3个成员变量:amount(账户金额)、interestRate和owner(账户名)。这3个成员变量中,amount和owner会因人而异,不同的账户这些内容是不同的,但所有账户的interestRate都是相同的。

amount和owner成员变量与账户个体有关,称为实例变量,隶属个体方法称为实例方法。

interestRate成员变量与个体无关,或者说是所有账户个体共享的,这种属性称为静态变量或者类变量,与个体无关的方法称为静态方法或者类方法。

示例:

ClassA,h文件

#import <Foundation/NSObject.h>

static int count;
@interface ClassA:NSObject
{
}
+(int) initCount;
//类级构造函数 静态构造函数
+(void) initialize;
@endClassA.m文件
#import "ClassA.h"
@implementation ClassA
-(id) init{
self = [super init];
count++;
return self;
}
+(int) initCount{
return count;
}
+(void) initialize {
count = 0;
}
@end调用的main函数:
ClassA * c1 = [[ClassA alloc] init];
ClassA * c2 = [[ClassA alloc] init];

//print count
NSLog(@"ClassA count : %i", [ClassA initCount]);

ClassA * c3 = [[ClassA alloc] init];
NSLog(@"ClassA count: %i", [ClassA initCount]);
//ClassA count:2
//ClassA count:3小总结:
init方法是默认构造函数,在这个构造函数中累计类变量count,在实例方法中可以访问类变量和类方法,但类方法不能访问实例变量

initCount方法是一个普通的类方法,用于返回类变量count

initialize方法是非常特殊的类方法,它是在类第一次访问时候被自动调用,因此它一般用来初始化类变量的,称为类级构造函数或者静态构造函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: