O'Reilly logo

Programming iOS 4 by Matt Neuburg

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

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]; ...

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required