Polymorphism
The compiler, even in the world of static typing, is perfectly happy for you to supply a subclass instance where a superclass type is declared. To see this, let’s start with the first line of the previous example:
UIButton* b = [UIButton buttonWithType:UIButtonTypeRoundedRect];
UIButton is a subclass of UIControl, which is a subclass of UIView. So it would be perfectly legal and acceptable to say this:
UIButton* b = [UIButton buttonWithType:UIButtonTypeRoundedRect]; UIView* v = b;
The variable b
is a UIButton instance, but I’m assigning it to a variable declared as a UIView. That’s legal and acceptable because UIView is an ancestor (up the superclass chain) of UIButton. Putting it another way, I’m behaving as if a UIButton were a UIView, and the compiler accepts this because a UIButton is a UIView.
What’s important when the app runs, however, is not the declared class of a variable, but the actual class of the object to which that variable points. Even if I assign the UIButton instance b
to a UIView variable v
, the object to which the variable v
points is still a UIButton. So I can send it messages appropriate to a UIButton. For example:
UIButton* b = [UIButton buttonWithType:UIButtonTypeRoundedRect]; UIView* v = b; [v setTitle:@"Howdy!" forState:UIControlStateNormal];
That code will cause the compiler to complain, because UIView doesn’t implement setTitle:forState:
. So I’ll calm the compiler’s fears by typecasting:
UIButton* b = [UIButton buttonWithType:UIButtonTypeRoundedRect]; ...
Get Programming iOS 4 now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.