Quick Links

The Basics of OOP

The basics:
Many will say that you need to learn a procedural language such as C before learning an object-oriented language. Many will also say that you should pick a language, and learn it. I feel opposite. I think you need a fundamental overview of what object oriented programming is on a non-code specific level. Let's start.

Objects: An object has two features: Attributes and behaviors. What are attributes? Imagine a person, their attributes are things such as blue eyes, brown hair. Attributes basically means the data in which the object is holding. Blue eyes is data. Brown eyes is data.

Behaviors, also called methods, would be actions that object has and can do. Again, imagine a person. This guy named NSDate is pretty smart, and can tell you how much time has passed since 1970 in a fraction of a second. That's just one of his many behaviors, that specific one is called timeintervalsince1970. How do we know that this NSDate guy even exists? He's floating around somewhere out there with all of his Behaviors and Attributes, how do I find him? The API. The API you're working with, (In iOS it's usually CocoaTouch, often times mixed with other Apple or third-party frameworks if you so choose). What if the objects provided in these API's don't do what I need them to do? Make your own object. How? By building a class.

Classes: Think of classes as blueprints to your object. Like a bike, the bike is the object but the blueprints of the bike are the class. The class creates all the attributes and behaviors that an object created from this class will possess. When you make your own class, you make your very own object, containing whatever attributes or behaviors you want them to.

A lot of times you use premade classes (nsstring, nsarray) and a lot of times you create your own classes to make custom objects. In Objective-C, we declare the attributes and behaviors either in the header file (public) or in the implementation file (private). What is the difference between public / private attributes or behaviors? Data encapsulation is a key practice in OOP, and it answers the question below.

Encapsulation
So, what is data encapsulation? It is basically combining the attributes and methods in the same entity. "Which in turn allows us to control access to the data (data hiding). By defining the data to be off-limits, another logically unconnected function cannot manipulate the data, only the object can do that. The point of this is for code-cleanliness, good organization and security to protect against stuff being manipulated that shouldn’t be. In an ideal world, you should always be able to change one of the methods in an implementation without it screwing up any subclass calling upon said method." - (Object Oriented Thought Process). Encapsulation also has a lot to do with the Scope of the object:

Scope
The scope of a variable is how far the variable accessed. Local attributes (variables) are owned by a specific method. Their scope is limited to that method. In Objective-C, that would appear as such:

int a is a local variable. mySecondMethod has no idea that "a" even exists. If we declare it like is, it would be an instance variable, and accessible by and method in the class. In Objective-C, that would look like this:

By defining it as a property (instance variable of your object), we can see / modify it's value in all methods of the class! Let's move on to another important topic related to properties, setters and getters.

Getters and Setters
So, what do getters and setters do? Basically, support the concept of data hiding. They provide controlled access to an objects data. They are also a great area to set values, rather than just saying int x = 3; in viewDidLoad, declare it in the setter.
That's basically what the @synthisize does in Objective-C, it generates the setters and getters for you behind the scenes. Cool huh? So what's a good reason why we would want to do this though, instead of just being lazy and using up synthesize? Well, let's say we have an integer called age. We don't want the age to be under zero. So we can set up the integer called age to not except any negative values pass to it. We set this up in the setter. It's basically a way of ensuring data integrity.

We've covered a lot so far. I'll take the time to take some commonly asked questions about these aspects of OOP:When I’m using Properties, do I declare the iVar as well in the header?
Nope. You really don’t need to do this:

It is just redundant. It won’t break anything if you choose to or like to… but there is no reason to do so. You will still see it often though just because of old-school convention.

Local vs Instance Variables vs Global Variables
Scope, scope, and again, scope. Local variables can be accessed only within the method in which they’re defined. Instance variables can be accessed within any instance of the class. Global can be accessed by any class in your project and will retain it's value through out the pass-off's. Be careful using these, as they are often overused and considered as poor coding convention by some.

What is a "Framework":
Frameworks, such as Cocoa and Cocoa Touch, are very powerful collections of prewritten classes in which we can utilize. Frameworks such as Cocoa Touch will become your best friend if you're an iOS developer. Reference the API's to learn everything each seemingly small class can do.

Should I use a property or an instance variable in Objective-C?
Properties are the standard coding convention today. Why? Well, let's re-iterate what the two do. When working with instance variables (aka ivars) you have to manually implement the setter and getters (accessor methods). Which can come in handy sometimes (see why in the "Getters and Setters" section). But, making a property instead will auto-synthesize the setter and getter methods. It basically saves on typing and adds functionality, such as the ability to set atomic vs nonatomic, strong vs weak, etc...

Back to Object Oriented Programming basics. We've covered some very important topics above, and it is advisable that you have a very solid understanding of the above before proceeding unless you wish to be in over your head and potentially have to start from scratch. I had to do that once... It's not fun.

Inheritance and Class Hierarchies:
Let's talk about one of the foundations of OOP: Inheritance. Inheritance is pattern in which the majority of programs implement in some way or another. So, what is it? This UML Diagram describes it best.

The Shape is the superclass. What does it do? Makes some pretty awesome shapes. As the UML shows, one of it's method's is Rectangles and circles are both shapes, but they each have their one unique qualities.
So to make a new shape, let's inherit from the Shape class, which in turn brings all the methods and variables that make a standard shape. We will call this subclass of the Shape class "Rectangle", and add in the methods and variables to make it a rectangle. We will do the same with Circle. Remember: When you instantiate (create) three different instances of a class, like 3 shape objects, each object contains its own set of attributes and behaviors provided by the class independent of each other. So, each time you create a new object, you get a brand new set of stuff to work with. If you would rather your class only be used once, which is sometimes the case in the MVC design pattern for the Model, you would need to make that class a Singleton. Design patterns such as MVC and singletons are discussed in-depth in my tutorial in the Design Patterns section.

Let's see another UML of inheritance to gain more understanding:

Polymorphism
Let's go back to the Shape class and add an empty method named draw. If a subclass asks shape to draw, shape can draw anything. That's not particular enough. Thus, shape is an abstract class and circle / rectangle calls upon it. This helps us with contracting because now no matter the shape, it will call the shapes draw method to draw it. Each subclass is responsible for implementing what shape to draw. In this way we have a shave framework that is truly polymorphic. If all that the shape method contained was this empty draw function and nothing else that would be an example of an abstract class. The required implementation of the Draw method is an example of Protocols, and each subclass doing it’s own thing with Draw is polymorphism.