Objective-C作为一种面向对象的编程语言,具有面向对象的基本特征,即:封装、继承和多态。主要介绍Objective-C中有关面向对象基本概念:类、对象、方法和属性等。

类是Objective-C中的一种重要的数据类型,是组成Objective-C程序的基本要素。Objective-C的类声明和实现包括两个部分:接口部分和实现部分。

  1. @interface Song: NSObject {

  2. }

  3. @end
  4. @implementation Song

  5. @end

使用关键字@interface(头文件跟C#和JAVA不一样),主要定义了类名、继承的父类、实现的协议、成员变量和方法等信息。下面的代码是Song类的接口部分声明。

  1. @interface Song : NSObject {
  2. NSString *title;
  3. NSString *artist;
  4. long int duration;
  5. }
  6. - (void)start;
  7. - (void)stop;
  8. - (void)seek:(long int)time;
  9. @end

使用关键字@implementation,主要实现了在接口部分定义的方法等信息。下面的代码是Song类的实现部分声明。

  1. @implementation Song
  2. - (void)start {
  3. //开始播放
  4. }
  5. - (void)stop {
  6. //停止播放
  7. }
  8. - (void)seek:(long int)time {
  9. //跳过时间
  10. }
  11. @end

两个可以放在一个文件,也可放在不同文件。成员变量在构造函数中初始化

Objective-C中方法定义非常古怪,它遵循了SmallTalk语法风格,它将一个方法名字分成几个部分。

• 定义了两个参数的方法,第一个参数是anObject,参数类型是id类型,第二个参数是index,参数类型是NSUInteger,这叫做多重参数。它的返回类型是void,方法签名是insertObject:atIndex:。方法类型标识符中都“-”代表方法是实例方法,“+”代表方法是类方法,关于实例方法和类方法我们将在后面内容中讨论。

如果上面的方法变成C或C+ +形式,则是下面的样子的:

-(void) insertObjectAtIndex(id anObject, NSUInteger index)

对于方法的调用通常也不称之为调用,而是称为发出消息,操作符号不是“.”而是“[⋯]”,如下所示:[myObject insertObject: ojb1 atIndex:0];即向myObject对象发出一个消息insertObject:atIndex:0。而在实际使用时候这两种叫法都会用,这不是严格划分。

从面向对象的封装角度考虑问题,要想访问类中的成员变量,是要通过方法访问的,成员变量前面要有作用域限定符(protected, public, private),这些存取权限修饰符我们将在后面介绍。成员变量的访问,是通过读取方法(getter)和设定方法(setter)。

  1. @interface Song : NSObject {
  2. NSString *title;
  3. NSString *artist;
  4. long int duration;
  5. }
  6. //操作方法
  7. - (void)start;
  8. - (void)stop;
  9. - (void)seek:(long int)time;
  10. //访问成员变量方法
  11. - (NSString *)title;
  12. - (void)setTitle:(NSString *)newTitle;
  13. - (NSString *)artist;
  14. - (void)setArtist:(NSString *)newArtist;
  15. - (long int)duration;
  16. - (void)setDuration:(long int)newDuration;
  17. @end
  1. @implementation Song
  2. - (void)start {
  3. //开始播放
  4. }
  5. - (void)stop {
  6. //停止播放
  7. }
  8. - (void)seek:(long int)time {
  9. //跳过时间
  10. }
  11. ... ...
  1. //访问成员变量方法
  2. - (NSString *)title {
  3. return title;
  4. }
  5. - (void)setTitle:(NSString *)newTitle {
  6. title = newTitle;
  7. }
  8. - (NSString *)artist {
  9. return artist;
  10. }
  11. - (void)setArtist:(NSString *)newArtist {
  12. artist = newArtist;
  13. }
  14. - (long int)duration {
  15. return duration;
  16. }
  17. - (void)setDuration:(long int)newDuration {
  18. duration = newDuration;
  19. }
  20. @end

采用了封装之后就可以通过存取方法访问属性,例如[mySongtitle]是取得title成员变量内容。如果不考虑封装的问题,单从技术上讲Objective-C,可以直接通过对象访问成员变量的,访问操作符是“->”,例如:mySong->title,也可以取得title成员变量的内容。

在上一小节中对于成员变量的访问,要通过读取方法(getter)和设定方法(setter)。在实现部分也要实现这些读取方法和设定方法,为了简化这些琐碎编码Objective-C2.0提出属性的概念,使用@property关键字在接口部分定义属性,在实现部分使用@synthesize关键字在组装和合成这些属性。

  1. @interface Song : NSObject {
  2. NSString *title;
  3. NSString *artist;
  4. long int duration;
  5. }
  6. //操作方法
  7. - (void)start;
  8. - (void)stop;
  9. - (void)seek:(long int)time;
  10. //访问成员变量方法
  11. @property(copy,readwrite) NSString *title;
  12. @property(nonatomic,retain) NSString *artist;
  13. @property(readonly) long int duration;
  14. @end

声明property的语法为:@property (参数) 类型 名字;,这里的“参数”主要分为3大类:基本类型不加内存管理、 内存管理限定,基本数据不需要进行内存管理

读写属性(readwrite/readonly);

• 内存管理(assign/retain/copy),这些内存管理的参数,我们将在内存管理小节部分介绍;

• 原子性atomicity(nonatomic),是关系线程线程安全的,atomicity是原子性的线程安全的,但是会影响性能。如果确定不考虑线程安全问题可以使用nonatomic。

属性访问用. 如:mySong.title=@"xxxx"; 或者[mySong setTitle:@"xxxx"],[mySong Title],因为属性有限定词后默认有GET SET方法; 成员变量用 ->如: mySong->title=@"xxxx";属性不保存值,通过属性把值传递给成员变量

  1. @implementation Song
  2. @synthesize title;
  3. @synthesize artist;
  4. @synthesize duration;
  5. - (void)start {
  6. //开始播放
  7. }
  8. - (void)stop {
  9. //停止播放
  10. }
  11. - (void)seek:(long int)time {
  12. //跳过时间
  13. }
  14. @end

出于初始化类中的成员变量的需要,可以提供一个方法用于此目的,这个方法就叫构造方法或构造方法(Constructor)。与C++和Java不同,Objective-C命名是

没有限制的,并且有返回值本身类型指针。

  1. @interface Song : NSObject {
  2. NSString *title;
  3. NSString *artist;
  4. long int duration;
  5. }
  6. //操作方法
  7. - (void)start;
  8. - (void)stop;
  9. - (void)seek:(long int)time;
  10. //访问成员变量方法
  11. @property(nonatomic,retain) NSString *title;
  12. @property(nonatomic,retain) NSString *artist;
  13. @property(readwrite) long int duration;
  14. //构造方法
  15. -(Song*) initWithTitle: (NSString *) newTitle
  16. andArtist: (NSString *) newArtist
  17. andDuration:( long int ) newDuration;
  18. @end

在Song类的定义中添加了一个方法,它一般用init开头命名,它的返回值很特殊,是返回值本身类型指针。并且有返回值本身类型指针。

  1. @implementation Song
  2. @synthesize title;
  3. @synthesize artist;
  4. @synthesize duration;
  5. //构造方法
  6. -(Song*) initWithTitle: (NSString *) newTitle
  7. andArtist: (NSString *) newArtist
  8. andDuration:(long int)newDuration {
  9. self = [super init];
  10. if ( self ) {
  11. self.title = newTitle;
  12. self.artist = newArtist;
  13. self.duration = newDuration;
  14. }
  15. return self;
  16. }
  17. ... ...
  18. @end

构造方法的实现代码几乎就是模式代码,基本上都是如下写法:

  1. self = [super init];
  2. if ( self ) {
  3. ……
  4. }
  5. return self;

• 其中使用 [super init] 来调用父类默认构造方法。 这个方法返回的实例对象指派给另一新个关键词:self。self很像 C++ 和 Java 的 this

• 还有if ( self ) 跟 ( self != nil ) 一样,是为了确定调用父类构造方法成功返回了一个新对象。当初始化变量以后,用返回self 的方式来获得自己的地址。

父类默认构造方法 -(id) init。技术上来说,Objective-C中的构造方法就是一个 "init" 开头的方法,而不像 C++ 与Java 有特殊的结构。

• 即便从封装的角度出发,实例成员变量应该定义为

@private,但作为一种面向对象的语言,Objective-C支持

@public、@private和@protected作用域限定。如果一个实例变量没有任何的作用域限定的话,那么缺省就是@protected。

• @public作用域限定的实例变量,可以在任何情况下访问;

• @private作用域限定的实例变量,只能在这个类里面才可以访问;

• @protected作用域限定的实例变量,可以在这个类里面和这个类的派生子类里面可以访问这个变量,在类外的访问是不推荐的,但也可以访问。

  1. @interface Access: NSObject {
  2. @public
  3. int publicVar;
  4. @private
  5. int privateVar;
  6. @protected
  7. int protectedVar;
  8. }
  9. @end
  10. #import "Access.h"
  11. @implementation Access
  12. @end
  1. #import <Foundation/Foundation.h>
  2. #import "Access.h"
  3. int main (int argc, const char * argv[]) {
  4. Access *a = [[Access alloc] init];
  5. a->publicVar = ;
  6. NSLog(@"public var: %i\n", a->publicVar);
  7. a->protectedVar = ;
  8. NSLog(@"protectedVar var: %i\n", a->protectedVar);
  9. //不能编译
  10. //a->privateVar = 10;
  11. //NSLog(@"private var: %i\n", a->privateVar);
  12. return ;
  13. }

@public、@private和@protected作用域限定只能修饰的实例成员变量,不能修饰类变量,更不能修饰方法类成员默认是protected

类变量不属于实例个体,类方法用+限定

  1. #import <Foundation/NSObject.h>
  2. static int count;
  3. @interface ClassA: NSObject
  4. +(int) initCount;
  5. +(void) initialize;
  6. @end
  1. #import "ClassA.h"
  2. @implementation ClassA
  3. -(id) init {
  4. self = [super init];
  5. count++;
  6. return self;
  7. }
  8. +(int) initCount {
  9. return count;
  10. }
  11. +(void) initialize {
  12. count = ;
  13. }
  14. @end

init方法是默认构造方法,在这个构造方法中累计类变量count,在实例方法中可以访问类变量的,但是类方法不能访问实例变量。initCount 方法是一个普通的类方法,用于返回类变量count,initialize方法是非常特殊的类方法,它是在类第一次访问时候被自动调用,因此它一般用来初始化类变量的,类似于C#中的静态构造方法。initialize在所有实例中只执行一次,并且在init之前执行。

  1. #import <Foundation/Foundation.h>
  2. #import "ClassA.h"
  3. int main( int argc, const char *argv[] ) {
  4. ClassA *c1 = [[ClassA alloc] init];
  5. ClassA *c2 = [[ClassA alloc] init];
  6. // print count
  7. NSLog(@"ClassA count: %i", [ClassA initCount] );
  8. ClassA *c3 = [[ClassA alloc] init];
  9. NSLog(@"ClassA count: %i", [ClassA initCount] );
  10. [c1 release];
  11. [c2 release];
  12. [c3 release];
  13. return ;
  14. }

ClassA count: 2
ClassA count: 3

在第一次实例化ClassA时候会调用两个方法: initialize类方法和实例构造方法init,然后再次实例化ClassA时候只是调用实例构造方法init,而没有调用initialize类方法。这样类变量count被一直累加,它隶属类因此c1实例可以访问,c2和c3都可以访问。

Objective-C语言的面向对象特性的更多相关文章

  1. 浅谈Objective—C中的面向对象特性

    Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...

  2. 一种C语言实现面向对象特性的继承,多态

    基类: //.h typedef int (*TELE_SEND_CB)(char *pdata, int len); //函数表结构 typedef struct tele_pro_base_vtb ...

  3. Java语言中的面向对象特性总结

    Java语言中的面向对象特性 (总结得不错) [课前思考]  1. 什么是对象?什么是类?什么是包?什么是接口?什么是内部类?  2. 面向对象编程的特性有哪三个?它们各自又有哪些特性?  3. 你知 ...

  4. Java语言中的面向对象特性

    面向对象的基本特征 1.封装性 封装性就是把对象的属性和服务结合成一个独立的相同单位,并尽可能隐蔽对象的内部细节,包含两个含义: ◇ 把对象的全部属性和全部服务结合在一起,形成一个不可分割的独立单位( ...

  5. Java语言中的面向对象特性:封装、继承、多态,面向对象的基本思想(总结得不错)

    Java语言中的面向对象特性(总结得不错) [课前思考] 1. 什么是对象?什么是类?什么是包?什么是接口?什么是内部类? 2. 面向对象编程的特性有哪三个?它们各自又有哪些特性? 3. 你知道jav ...

  6. C++对C语言的非面向对象特性扩充(3)

    今天要讲的是C++作用域运算符"::",强制类型转换的扩充,C++中相对于C中malloc和free函数的运算符new和delete,以及C++对C的一个重要扩充:引用(refer ...

  7. Javascript面向对象特性实现封装、继承、接口详细案例——进级高手篇

    Javascript面向对象特性实现(封装.继承.接口) Javascript作为弱类型语言,和Java.php等服务端脚本语言相比,拥有极强的灵活性.对于小型的web需求,在编写javascript ...

  8. javascript进阶——面向对象特性

    面向对象的javascript是这门语言被设计出来时就考虑的问题,熟悉OOP编程的概念后,学习不同的语言都会发现不同语言的实现是不同的,javascript的面向对象特性与其他具有面向对象特性的语言的 ...

  9. .NET面向对象特性之封装

    .NET面向对象特性之封装 面向对象的基本内容由:类.对象.属性.方法.字段构成. 面向对象的三大特性:继承.多态.封装. 关于面向对象的特性很多人都把目光转向了继承.多态和接口,却很少有人提及过封装 ...

随机推荐

  1. JS-005-常见下拉列表 Select 和 datalist

    下拉列表在我们日常的网页浏览的过程中,随处可见,是 web 编程过程中大家非常熟悉的一个页面元素,随着 HTML 语言的日益强大,其在广大攻城狮的手中可谓是千变万化,有了很多不同的实现方式.本文主要以 ...

  2. 用JQuery给图片添加鼠标移入移出事件

    $("#addLineImg").mouseover( function(){ $("#addLineImg").attr("src",&q ...

  3. UpdatePanel AsyncPostBackTrigger PostBackTrigger 区别

    1.使用代码的方式进行编写. 2. Trigger属性: 1)AsyncPostBackTrigger :只是UpdatePanel中指定的进行了局部刷新. 2)PostBackTrigger : 整 ...

  4. iOS 集成银联支付

    下载地址:https://open.unionpay.com/upload/download/Development_kit85427986.rar 其实我找了半个小时 也不知道怎么就下载好了 这个我 ...

  5. saltstack之(六)配置管理state

    配置管理是saltstack工具最重要的模块之一,也是学习saltstack之后使用最多的一个功能.可以轻松实现上百台上千台甚至上万台服务器的管理工作. 1.使用state模块进行配置管理,编写sls ...

  6. linux多个python版本下导致no request报错

    解决办法: sudo apt-get install uwsgi uwsgi-core uwsgi-plugin-python sudo apt-get install uwsgi-plugin-py ...

  7. Android 关于ListView中adapter调用notifyDataSetChanged无效的原因

    话说这个问题已经困扰我很久了,一直找不到原因,我以为只要数据变了,调用adapter的notifyDataSetChanged就会更新列表,最近在做微博帐号管理这一块,想着动态更新列表,数据是变了,但 ...

  8. iptables调试方法

    iptables调试时,使用到raw表.ipt_LOG内核模块.日志记录在kern.log中. 具体的步骤如下: 1.准备ipt_LOG内核模块 modprobe ipt_LOG 2.使用raw表,加 ...

  9. H3C Series Router MSR26-00与F3736 VPN IP SEC

    注:建立链接之后经常断线,需要两边进行PING通才可以.待解决.

  10. mysql修改表名,列名,列类型,添加表列,删除表列

    alter table test rename test1; --修改表名 ); --添加表列 alter table test drop column name; --删除表列 ) --修改表列类型 ...