Intro to Object-Oriented Design in Swift: Part 1/2
- Getting Started
- The Basics Of Objects
- Minor Digression: Initialization and Properties
- Minor Digression: Class versus Struct
- Describing the Object
- A Minor Digression: Class Methods vs. Instance Methods
- Adding Basic Methods to Your Class
- Overriding Methods
- Building out the User Interface
- Hooking Your Data to Your View
- Model-View-Controller Encapsulation of Logic
- Creating Subclasses via Inheritance
- Housing Logic in the Model Class
- Where To Go From Here?
Update 4/11/2015: Updated for Xcode 6.3 / Swift 1.2
A huge piece of the programming puzzle in working with Cocoa, Objective-C and Swift is Object-Oriented Programming. Almost all modern programming languages use this approach, and wrapping your head around its concepts and patterns can be incredibly helpful when reading and writing code.
Underneath the relation between
UIButton are the fundamental concepts of object-oriented design. By understanding these concepts you’ll have a better grasp on why things are organized the way they are in Cocoa and Cocoa Touch, and you’ll be a more thoughtful programmer when writing your own apps and frameworks.
In this series you’ll learn more about object-oriented design, including the following concepts:
- The Basics Of Objects
- Common Object-Oriented Patterns
This series is designed for developers who are fairly new to programming overall. You likely haven’t worked with other languages extensively, and you’re not quite sure why everything is being done in a particular way.
This tutorial will cover object-oriented design principles rather than specific syntax, so you should already know the basics of Swift and Xcode before reading on. If you need a refresher on the basics, check out the Quick Start Tutorial.
In order to try and understand some of these concepts in a more concrete manner, you’ll build an application called Vehicles. This uses one of the most common metaphors for translating real-world items into virtual objects: the “vehicle”, which could be a bicycle, a car, or really anything with wheels.
For instance, this is a vehicle:
But so is this:
In this part of the tutorial, you’ll create a data model using basic object-oriented techniques to represent all of these vehicles, and a simple application which implements the data model and displays vehicle data to the user.
Download the starter project, which contains a basic framework for the application you’ll use to learn about Object-Oriented Programming.
The Basics Of Objects
In object-oriented programming, the basic goal is to break down the characteristics of a “thing” to create an object or objects that describe what that thing is and what that thing does.
Sometimes, as with vehicles, your “thing” has a real-world equivalent. Sometimes it doesn’t, as with the many different types of
UIViewController objects. For the sake of simplicity, you’ll start out by creating objects that have real-world analogs.
In order to answer the question of what a “thing” is, you have to first determine what its defining characteristics are.
Other languages will refer to this as a “field”, a “member”, or even just a “variable”. However, in Swift the defining characteristics of an object are shown by its properties.
Think about the generic concept of a “vehicle” for a moment — something that describes all of the photos above. What common characteristics of a “vehicle” spring to mind?
- It has a number of wheels.
- It has some sort of power source, whether human, gas, electric, or hybrid, which makes it move.
- It has a brand*, like Ford, Chevy, Harley-Davidson, or Schwinn.
- It has a model name like Mustang, Corvette, Sportster, or Fastback.
- It has a year associated with its manufacture.
*- this is sometimes referred to in cars and trucks as a “Make”, but we’ll refer to it as a “brand” across the board for clarity.
Now that you have the basic characteristics of a vehicle, you can create an Object with these characteristics.
The file Vehicle.swift defines a class of objects named
Open Vehicle.swift and add the following code within the
var brandName = "null"
var modelName = "null"
var modelYear = 0
var powerSource = "null"
var numberOfWheels = 0
These property declarations describe the characteristics of the object you want to keep track of. For now you are just providing placeholder values so that the Swift compiler can infer the types as a
Int. (Later, in Part 2, you will add a real initializer to get rid of these dummy, placeholder values. This is why you are not using Swift Optionals to represent them.)
Minor Digression: Initialization and Properties
One of the important safety features of Swift is how it enables and enforces proper initialization of objects. This means that it’s virtually impossible to use uninitialized memory. The above properties are called stored properties and must be initialized either by setting them explicitly as you have done, or by initializing them in an
init() method. If you supply all of your stored properties with values, the compiler won’t require you to explicitly set them in the
Minor Digression: Class versus Struct
In Swift, you can define an object-like thing with the keyword
struct. In this tutorial, you will be using
class to define objects because these allow you to build class hierarchies and override methods. Structs, while very useful for many things, are more static in nature and don’t allow for this. For more information on when to use a
class versus a
struct see The Swift Programming Language Book.
Describing the Object
On to the second critical question for every object — what exactly does the object do?
A programmatic description of what an object does is almost universally called a method. Think about the common actions of the vehicles in the photos above:
- It can go forward
- It can go backward
- It can stop
- It can turn
- It can change gears
- It can make some sort of noise (e.g. a horn or a bell)
Most often, you’d be using methods that don’t return anything. However, to make it a little easier to display what’s happening in your app, you’re going to use some methods that return
A Minor Digression: Class Methods vs. Instance Methods
You’ve probably noticed when writing code that some methods have the
class keyword in front of them. These indicate that a method is a Class method as opposed to a normal Instance method.
The simplest way to think of the difference is like a schematic blueprint in the physical world: There’s only one blueprint for something, but using that blueprint, you can make many different copies.
A class method is an action that can be performed with that blueprint, but without creating a specific copy of the object from that blueprint. For example,
UIColor has the class method
blackColor() that returns a new instance of
UIColor set to black.
An instance method, requires a specific copy of the object created using that blueprint to perform any action. For example, the
"Hello There" has an instance method
lowercaseString that would return
"hello there". A class method
lowercaseString wouldn’t make any sense since that’s just the blueprint for a string – there’s no actual text to lower case!