动态类型和动态绑定,id可以表示任何指针类型,定义id变量不加*

多态性是指在父类中定义的成员变量和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一个变量和方法在父类及其各个子类中具有不同的表现形式。我们通过一个例子理解什么多态,例如:“几何图形”类的“绘图”方法,在它的子类“椭圆形”和“三角形”中也都有“绘图”的方法,但是“绘图”方法功能都不同。

Graphics(几何图形)类是Ellipse(椭圆形)类和Triangle(三角形)类的父类,Ellipse和Triangle重写了onDraw方法。

@interface Graphics : NSObject {
}
-(void)onDraw;
@end
#import <Foundation/Foundation.h>
#import "Graphics.h"
@interface Ellipse : Graphics {
}
@end
#import <Foundation/Foundation.h>
#import "Ellipse.h"
@implementation Ellipse
-(void)onDraw {
NSLog(@"绘制椭圆形");
}
@end
#import <Foundation/Foundation.h>
#import "Graphics.h"
@interface Triangle: Graphics {
}
@end
#import <Foundation/Foundation.h>
#import "Triangle.h"
@implementation Triangle
-(void)onDraw {
NSLog(@“绘制三角形");
}
@end
#import <Foundation/Foundation.h>
#import "Graphics.h"
#import "Ellipse.h"
#import "Triangle.h"
int main (int argc, const char * argv[]) {
Graphics *graphics;
graphics = [[Ellipse alloc] init];
[graphics onDraw];
[graphics release];
graphics = [[Triangle alloc] init];
[graphics onDraw];
[graphics release];
return ;
}

id 是泛类型 (generic data type), 可以用来存放各种类型的对象, 使用 id 也就是使用“动态类型”。

int main (int argc, const char * argv[]) {
id graphics;
graphics = [[Ellipse alloc] init];
[graphics onDraw];
[graphics release];
graphics = [[Triangle alloc] init];
[graphics onDraw];
[graphics release];
return ;
}

把Graphics *改成id类型,程序运行的结果没有任何影响。由于动态类型的关系,id 在执行时,Objective-C 的执行环境会找出该 id 所代表的原来类型,所以根本没有所谓的转型。id 并不是自动的转换成 Ellipse和 Triangle的父类,而是在执行期间, 由执行环境辨认出 id 实际代表的类型为Ellipse还是Triangle。因此在这个例子中id 与Graphics没有任何关系。

• 定义两个类:“矢量”和“标量”类。

• 矢量”即有方向和大小的量,如物理学中的“力”。标量为没有方向只有大小量,如物理学中的“功”。

@interface Vector : NSObject {
double vec1;
double vec2;
}
@property double vec1,vec2;
-(void)print;
-(void)setVec1:(double)v1 andVec2:(double) v2;
-(Vector *)add:(Vector *)v;
@end
#import "Vector.h"
@implementation Vector
@synthesize vec1,vec2;
-(void) setVec1:(double) v1 andVec2:(double)v2 {
vec1 = v1;
vec2 = v2;
}
-(Vector *)add:(Vector *)v {
Vector *result = [[Vector alloc] init];
[result setVec1:vec1 + [v vec1] andVec2: vec2 +
[v vec2]];
return result;
}
-(void)print {
NSLog(@"%g, %g",vec1,vec2);
}
@end
@interface Scalar : NSObject {
double scal;
}
@property double scal;
-(void)print;
-(void)setScal:(double)sval;
-(Scalar *)add:(Scalar *)s;
@end
#import "Scalar.h"
@implementation Scalar
@synthesize scal;
-(void)print {
NSLog(@"%g", scal);
}
-(void)setScal:(double)sval {
scal = sval;
}
-(Scalar *)add:(Scalar *)s {
Scalar *result = [[Scalar alloc] init];
[result setScal:scal + [s scal]];
return result;
}
@end
#import "Vector.h"
#import "Scalar.h"
int main (int argc, const char * argv[]) {
Scalar *scA =[[Scalar alloc] init];
Scalar *scB =[[Scalar alloc] init];
Vector *vecA =[[Vector alloc] init];
Vector *vecB =[[Vector alloc] init];
id scAandB;
id vecAandB;
[scA setScal: 10.5];
[scB setScal: 13.1];
[vecA setVec1: 3.2 andVec2: 4.7];
[vecB setVec1: 32.2 andVec2: 47.7];
... ...
[vecA print];
NSLog(@" + ");
[vecB print];
NSLog(@" = ");
vecAandB = [vecA add: vecB];
[vecAandB print];
[scA print];
NSLog(@" + ");
[scB print];
NSLog(@" = ");
scAandB = [scA add: scB];
[scAandB print];
[scA release];
[scB release];
[scAandB release];
[vecA release];
[vecB release];
[vecAandB release];
return ;
}

运行结果:

3.2, 4.7
+
32.2, 47.7
=
35.4, 52.4
10.5
+
13.1
=
23.6

• scAandB和vecAandB对象都是动态类型,都可调用以 "print"和"add"方法。

虽然id类型可以任何类型的对象,但是不要滥用,如果能够确定对象数据类型时候,要使用“静态类型”,“静态类型”在编译阶段检查错误,而不是在执行阶段。而且“静态类型”程序可读性好。

Objective-C语言多态性的更多相关文章

  1. Java 语言多态性

    https://www.ibm.com/developerworks/cn/java/java-language-polymorphism/index.html 定义多态性 多态性是面向对象编程中的一 ...

  2. iOS开发核心语言Objective C —— 全部知识点总结

    本分享是面向有意向从事iOS开发的伙伴及苹果产品的发烧友,亦或是已经从事了iOS的开发人员,想进一步提升者.假设您对iOS开发有极高的兴趣,能够与我一起探讨iOS开发.一起学习,共同进步.假设您是零基 ...

  3. iOS开发核心语言Objective C —— 面向对象思维、setter和getter方法及点语法

    本分享是面向有意向从事iOS开发的伙伴们.或者已经从事了iOS的开发人员.假设您对iOS开发有极高的兴趣,能够与我一起探讨iOS开发.一起学习,共同进步.假设您是零基础,建议您先翻阅我之前分享的iOS ...

  4. 【转】从Go、Swift语言出发

    Google于2009年第一次提出了Go的构思,Facebook在去年春天引入了Hack,随后不久Apple也发布了其Swift语言. 在战争中,胜利者写历史书:在科技中,赢的公司都在写编程语言.互联 ...

  5. 从Go、Swift出发:语言的选择需谨慎

    本文转自 : http://www.csdn.net/article/2014-12-09/2823025 摘要:无论是开源的Go,还是闭源的Swift,新的语言总是利弊一体.不过可以确定的是,新的语 ...

  6. Windows下搭建objective C开发环境

    摘自:http://blog.csdn.net/zhanghefu/article/details/18320827 最近打算针对iPhone.iPod touch和iPad开发一些应用,所以,需要开 ...

  7. Objective C Runtime 开发介绍

    简介 Objective c 语言尽可能的把决定从编译推迟到链接到运行时.只要可能,它就会动态的处理事情.这就意味着它不仅仅需要一个编译器,也需要一个运行时系统来执行变异好的代码.运行时系统就好像是O ...

  8. Windows在结构objective C开发环境

    对于近期打算iPhone.iPod touch和iPad开发一些应用程序,所以.需要开始学习Objective C(苹果推出的类似C语言的开发语言).因为苹果的自我封闭的产业链发展模式(从芯片.机器. ...

  9. Objective C语言中nil、Nil、NULL、NSNull的区别

    以下内容是基于搜集整理的网上资料,供参考. nil:指向Objective C语言中对象的空指针,其定义值为(id)0. Nil:指向Objective C语言中类(Class)的空指针,其定义值为( ...

随机推荐

  1. (转)as3效率优化

    1.改进算法无论对于那一种程序,好的算法总是非常重要的,而且能够极大地提高程序性能,所以任何性能的优化第一步就是从算法或者说程序逻辑的优化开始,检查自己的程序是否有多余的运算,是否在没有必要的时候做了 ...

  2. scala case class

    在我们详细介绍Scala的Case class和模式匹配之前,我们可以通过一个简单的例子来说明一些基本概念.我们设计一个函数库,这个函数库可以用来计算算术表达式,为简单起见,我们设计的算术表达式只侧重 ...

  3. HDU1978 记忆化搜索

    How many ways Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  4. ArcGIS AddIN之工具不可用

    AddIN做的工具,第一次打开时工具亮起(可用),第一次点击之后工具就灰掉(不可用) 原因:该工具没有找到响应函数 具体原因:之前做的好多工具,好多个项目,好多代码.现在统一放到一个项目中,一个工具条 ...

  5. 一個相當簡潔的名字—Dyson Humidifier

    現在不止是白領級人物開始網購使用加濕器對皮膚的一個乾燥祈禱防護作用.目前新研究的一款家用的加濕器,戴森首款推出. 作為戴森的首款加濕器產品,該公司賦予了它一個相當簡潔的名字——Dyson Humidi ...

  6. session生命周期

    session生命周期 原文链接:http://blog.sina.com.cn/s/blog_72c8c1150100qpgl.html 文中黄色字体为我的标记修改或添加 Session保存在服务器 ...

  7. IOS第一天

    第一天(hello world) 1>UIView所有的控件都继承UIView,倒位置,宽度和高度..UIButton UILable 2>UIViewController .h 是声明属 ...

  8. HDU 1264 Counting Squares(线段树求面积的并)

    Counting Squares Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  9. 浏览器中Javascript单线程分析

    线程这个特性对于一门语言环境来说是尤其重要的,在Java/C++环境下都提供了多线程API操作. 但在Javascript中据说代码执行时单线程的,大量计算的逻辑会阻塞浏览器HTML渲染,但setTi ...

  10. 《Linux内核设计与实现》CHAPTER18阅读梳理

    <Linux内核设计与实现>CHAPTER18阅读梳理 [学习时间:2hours] [学习内容:bug的来源分析:bug调试途径] 一.bug来源 1.内核中的bug 内核中的bug表现得 ...