9.7 练习

1.如果在代码清单9-1中执行加法之后(但是在释放compResult的内存之前)插入以下消息

表达式,将发生什么情况?


[compResult reduce];


试一试并查看结果。

2.可以将代码清单9-2中定义的id变量dataValue分配给在第8章中定义的Rectangle对象吗?就是说,表达式


dataValue=[[Rectangle alloc]init];


是否合法?为什么?

3.给第8章中定义的XYPoint类中添加一个print方法。让它以格式(x, y)显示一个点。然后修改代码清单9-2来结合一个XYPoint对象。使修改后的程序创建一个XYPoint对象,设置其值,把这个值分配给id变量dataValue,最后显示它的值。

4.基于本章关于参数和返回类型的讨论,修改Fraction和Complex类的add:方法来选取并返回id对象。然后编写一个程序并添加以下代码序列:


result=[dataValue1 add:dataValue2];

[result print];


其中,result、dataValue1和dataValue2都是id对象。确保在程序中适当地设置dataValue1和dataValue2,并且在程序结束之前释放所有的对象。

注意:必须将方法名改为非add:的其他名称。这是因为系统NSObjectController类也有一个add:方法。如9.4小节所述,如果在不同的类中有多个同名的方法,并且在编译时不知道接收器的类型,那么编译器就会执行一致性检查,确保参数和返回类型在名称类似的方法之间保持一致。

5.根据本章中使用的Fraction和Complex类定义以及如下定义


Fraction*fraction=[[Fraction alloc]init];

Complex*complex=[[Complex alloc]init];

id number=[[Complex alloc]init];


确定以下消息表达式的返回值。然后将它们键入一个程序,验证结果。


[fraction isMemberOfClass:[Complex class]];

[complex isMemberOfClass:[NSObject class]];

[complex isKindOfClass:[NSObject class]];

[fraction isKindOfClass:[Fraction class]];

[fraction respondsToSelector:@selector(print)];

[complex respondsToSelector:@selector(print)];

[Fraction instancesRespondToSelector:@selector(print)];

[number respondsToSelector:@selector(print)];

[number isKindOfClass:[Complex class]];

[number respondsToSelector:@selector(release)];

[[number class]respondsToSelector:@selector(alloc)];