How to cast 'Class A' to its subclass 'Class B' - Objective-C

时光总嘲笑我的痴心妄想 提交于 2019-11-28 21:10:56

Casting object variables in Objective-C is usually a mistake (there are a few cases where it's right, but never for this sort of thing). Notice that you aren't casting an object — you're casting a pointer to an object. You then have a pointer of type ClassB*, but it still points to the same instance of ClassA. The thing pointed to hasn't changed at all.

If you really want to convert instances of ClassA to ClassB, you'll need to write a ClassB constructor method that can create a ClassB instance from a ClassA. If you really need to add instance variables, this might be your best choice.

As Jason said, though, it's often a good idea to try a category first.

You can't just cast a super class to its subclass. It doesn't actually implement any of your added variables/properties or methods. As soon as you try to message it with a method you define on your subclass, you are going to get a runtime exception and your application is going to quit. You can only safely cast in one direction: from more specific to more general. I.e., you can cast our ClassB to a ClassA safely, using only the methods and properties of ClassA, but not the other way around.

Think of it this way: you have a Car (the parent class) and a FourDoorSedan (the subclass). Every car has an engine and two doors. Now, let's say you are getting a car from somewhere, and that's really all you know about it. You tell the operator, that car is a FourDoorSedan, but in fact it turns out it's not. So when the operator does something like: openBackPassengerDoor, what happens? There are only two doors!! It's the same here.

If you just want to add a little functionality to ClassA, check out Objective-C Categories, they're probably what you want and no casting will be required. Read the documentation carefully, however, because they are not without their caveats.

If you just want to add a method to existing objects, subclassing is not the correct way. You can add method to existing classes (and their instances) using a language feature called category.

Example:

//"ClassA+doSomethingCool.h"
@interface ClassA (doSomethingCool)
- (ClassA *)doSomethingCool:(int)howCool;
@end


//"ClassA+doSomethingCool.m"
@implementation ClassA (doSomethingCool)
- (ClassA *)doSomethingCool:(int)howCool
{

}
@end

Casting doesn't convert from one type of object to another. You can't force some library to change type of object and create another type of objects unless it utilizes some factory pattern.

What happens when you call one of your subclass methods on the returned object?

ClassB * objB;
objB = (ClassB *)doSomethingCool(10);
[objB subClassMethod];

Obj-C is pretty free and lose with types, you don't even need to know the type before hand, eg. you could change all of your ClassB references to id. I know it's safer to know you have the expected type but if your code is correct it shouldn't matter.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!