Objective-C introduction - 3

<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>

去我的目录

我们接着来看objective c中面向对象的特性。要谈到面向对象,就不可能不说继承和多态。
其实,我们之前就已经谈到了继承,因为在objective c中,所有类都是从NSObject继承而来的。
继承,可以理解为“is-a”的关系,这个概念相信对大部分人来说都在熟悉不过了,关于C++和Java的任何一本书都会详细介绍这个概念,这里我不再赘述,直接上例子。

// Rectangle.h
#import <Foundation/NSObject.h>
@interface Rectangle:NSObject {
    int width, height;
}
- (Rectangle*) initWithWidth:(int)w andHeight:(int)h;
- (void) setWidth: (int)w;
- (void) setHeight: (int)h;
- (void) setWidth: (int)w andHeight:(int)h;
- (int) width;
- (int) height;
- (void) print;  // printf("width is %i, height is %i/n", [self width], [self height]);
@end


- (Rectangle*) initWithWidth:(int)w andHeight:(int)h- (void) setWidth: (int)w andHeight:(int)h  都是带多个参数的函数声明(参见第一篇)。

我们再实现一个正方形的类,继承矩形。
// Square.h
#import "Rectangle.h"
@interface Square:Rectangle {
}
- (Square*) initWithSize: (int)s;
- (void) setSize: (int)s;
- (int) size;
@end
// Square.m
@implementation Square
- (Square*) initWithSize: (int)s {
    if( self = [super init] ) {
       [self setSize:s];
   }
   return self;
}
- (void) setSize: (int)s {
    width = s;
    height = s;
}
- (int) size {
    return width;
}
- (void) setWidth: (int)w {
    [self setSize:w];
}
- (void) setHeight: (int)h {
    [self setSize:h];
}
- (void) print {
   printf( "the size is %i/n", [self size] );
}
@end

上面这个正方形类,继承了矩形类的成员变量。但是由于正方形的几何特殊性(长=宽),所以在正方形类中添加了三个方法。
分别是initWithSize,setSize,size 。另外,我们重载了矩形类中的setWidthsetHeight 方法,因为正方形不允许分别设置长和宽。
如何使用:
int main( int argc, char* argv[] ) {
    Rectangle* rect = [[Rectangle alloc] initWithWidth:10 andHeight:5];
    Square* sq = [[Square alloc] initWithSize:10];
    [rect print];
    [sq print];
    [rect release];
    [sq release];
}

 

<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>

有了继承,我们就来说一说多态性。C++中虚函数的概念相信大家都不陌生,它通过一个虚拟表(virtual table)实现了动态绑定(dynamic binding)。
在objective c中也有类似的概念。
我们就以上面两个类为例子:
int main ( int argc, char* argv[] ) {
    Rectangle *rect = [[Rectangle alloc] initWithWidth:10 andHeight:5];
    Square *sq = [[Square alloc] initWithSize: 5];
    id shape;
    
    shape = rect;
    [shape print];   // call the Rectangle's print

    shape = sq;
    [shape print];   // call the Square's print

    ... ...
}

这里,引入了objective c的一个很重要的关键词 id
我们可以将id理解为C++中的void*,所以我们能将rect和sq都赋值给shape。
那么shape是怎么知道调用哪个版本的print的呢?
还记得第一篇中我们提到的message的概念么?虽然id不知道如何响应print,但是它可以把这个消息传递给rect或者sq。

<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>

和c++与Java一样,objective c也支持run-time的类类型检查
- (BOOL) isKindOfClass: classObj
用于判断该对象是否属于某个类或者它的子类。

// true

如: if( [sq isKindOfClass: [Rectangle class]] == YES ) {}

- (BOOL) isMemberOfClass: classObj
用于判断该对象是否属于某个类(这里不包括子类)

// true

如: if( [sq isMemberOfClass: [Rectangle class]] == NO ) {}

- (BOOL) respondsToSelector: selector
用于判断该对象是否能响应某个消息。这里,我们可以将@selector后面带的参数理解为C++中的函数指针。
注意:1)不要忘了@ 2)@selector后面用的是(),而不是[]。3)要在消息名称后面跟:,无论这个消息是否带参数。

// true

如: if( [sq respondsToSelector: @selector(setSize:)] == YES ) {}

+ (BOOL) instancesRespondToSelector: selector
用于判断该类是否能响应某个消息。这是一个静态函数。

// true

如: if( [Square instancesRespondToSelector: @selector(setSize:)] == YES ) {}

<script type="text/javascript"> </script> <script type="text/javascript"> </script>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值