我正在寻找关于这是否是一个好习惯的建议。我为长篇解释道歉。我有一个大的x,y坐标网格。网格由不同类的对象占用,所有对象都有不同的方法和数据。当用户触摸网格坐标时,我正在寻找最简单的方法将程序路由到正确的方法,具体取决于对象类型。
我将使用形状作为解释我正在做的事情的简单方法。假设我有两个类,Circle和Square都有一个父类Shape。
我将Circle类和Square类的对象添加到名为shapeManager的NSMutableArray中。当用户触摸网格时,我想找出该坐标的对象类型,以便我可以路由到适当的方法。
for (Shape *shape in shapeManager) {
if (shape.type == kCircle) {
[self circleSelected:shape];
}
}
-(void)circleSelected:(circle *)circle { }
当我这样做时,我是否将指针改为另一个类?这有什么缺点吗?我只是在寻找一种处理网格上的触摸事件的好方法,当生活在该坐标处的对象是未知的并且具有多个可能的类时。
答案 0 :(得分:0)
从NSObject
派生的所有类都继承了一个名为isMemberOfClass:
的方法,该方法将使用内省测试类成员资格。您可能会发现这对您的目的很有用。
for (Shape *shape in shapeManager) {
if ([shape isMemberOfClass:[Circle class]]) {
[self circleSelected:(Circle*)shape];
}
else if ([shape isMemberOfClass:[Square class]]} {
[self squareSelected:(Square*)shape];
}
}
还有一个isKindOfClass:
方法执行类似的测试,但如果接收对象是您要测试的类的子类,也会返回true。
答案 1 :(得分:0)
如何实施'选择' Shape的子类中的方法,它是Circle和Square类。然后,该对象可以调用“已选择”#39;方法直接。
for (Shape *shape in shapeManager) {
[self selected];
}
圈子实施
@interface Circle: Shape
{
}
@implementation Circle
-(void)selected
{
// do your circle select stuff here
}
@end
方形实施
@interface Square: Shape
{
}
@implementation Square
-(void)selected
{
// do your square select stuff here
}
@end
答案 2 :(得分:0)
如果您添加另一个Shape
,您的方法的缺点就是 - 您最终必须更改此代码。另一种方法是向userSelected
类添加一个方法,比如Shape
,让每个子类重写此方法,以执行适合于它们所代表的形状的任何方法。
在另一种方法中,你的循环变为:
for(Shape *shape in shapeManager)
[shape userSelected];
例如,Circle
获得了一种方法:
@implementation Circle
// override Shape's userSelected and do what a circle needs to do
- (void) userSelected
{
...
}
您选择哪种方法取决于您,没有正确回答本身,但面向对象的风格通常有利于后者。
评论跟进
从孩子到父母,你不需要演员,但可以包括一个 - 这是基于继承的面向对象语言的基础,如Obj-C。
另一方面,从父母到孩子,在Obj-C(a)中需要演员和(b)应该受到支票的保护 - 因为你不知道孩子中的哪一个(如果有的话)有。在Obj-C(a)中告诉编译器你认为你知道它应该信任你,(b)你是否在检查以确保它!
您(b)与[<obj> isKindOfClass:[<classname> class]
一起测试<obj>
是否属于<classname>
或的任何子女;或者您可以使用isMemberOfClass
来测试<obj>
类型<classname>
但 的任何子项。前者更容易扩展(例如,您可以从Rectangle
开始Shape
开始,然后将Square
作为Rectangle
; isMemberOfClass:[Rectangle class]
的测试对于YES
和Rectangle
,{}}} Square
isKindOfClass:[Rectangle class]
YES
只有Rectangle
。
通常不需要显式测试,因为方法调度通常包含它 - 如上面的[shape userSelected]
,它将在运行时根据userSelected
的实际类型调用shape
的适当实现。当需要使用测试进行显式测试时,可以使用强制转换。
是的,混合类型的集合很常见,实际上它们是基于继承的面向对象语言(如Obj-C)的另一个板块。
[注意:Obj-C缺少哪些其他语言是限制集合可能包含的内容的方式。例如。 NSMutableArray
可以包含任何对象,而在您的情况下,能够说NSMutableArray of Shape
将其限制为Shape
及其子类可能是有益的。 C#,Ada,甚至C ++(尽管它强制执行任何东西)都提供了这一点。如果您需要,您可以在Obj-C中自己完成,请参阅this answer。]