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

一 面向对象的基本特性

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;
}
......
@end
6 属性

在定义和实现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 *)newArtist 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;
@end
ClassA.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方法是非常特殊的类方法,它是在类第一次访问时候被自动调用,因此它一般用来初始化类变量的,称为类级构造函数或者静态构造函数。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值