What Is the Difference Between Instance Methods and Type Methods in Swift

Download Your Free Copy of
The Missing Manual
for Swift Development

The Guide I Wish I Had When I Started Out

Join 20,000+ Developers Learning About Swift Development

Download Your Free Copy

Before I can explain the difference between instance methods and type methods, you first need to understand what an instance is and what a type is. Let me show you an example. Fire up Xcode and create a playground. Remove the contents of the playground and declare a struct with name User. The struct declares one constant property, name of type String.

struct User {

    // MARK: - Properties

    let name: String

}

User is a type. We can create a user by invoking the memberwise initializer of User. The user we created is an instance of User.

let jane = User(name: "Jane")

What Are Instance Methods in Swift?

Now that you know what the difference is between an instance and a type, you may already know what the difference is between an instance method and a type method in Swift. Let's add a method to the User struct.

struct User {

    // MARK: - Properties

    let name: String

    // MARK: - Instance Methods

    func greeting() -> String {
        "Hello \(name)!"
    }

}

The method we defined, sayHello(), is an instance method. This suggests that we need an instance to execute the method. Let's use the user we created earlier to invoke the sayHello() method.

let jane = User(name: "Jane")

jane.sayHello()

You can see the result in the results view on the left.

"Hello Jane!"

What happens if we call sayHello() on the type, that is, the User struct. The compiler throws an error, telling us that sayHello() cannot be called on the User struct. This isn't surprising because sayHello() is an instance method and needs to be called on a User instance.

Instance Methods and Type Methods in Swift

What Are Type Methods in Swift?

You learned what an instance method is and that an instance method cannot be called on a type. This brings us to the question "What is a type method in Swift?" Let's create a type method to illustrate the difference. We add a type method to User and name it createUser(with:). Notice that we prefix the type method with the static keyword. That keyword tells the compiler createUser(with:) is a type method.

struct User {

    // MARK: - Properties

    let name: String

    // MARK: - Instance Methods

    func sayHello() -> String {
        "Hello, \(name)"
    }

    // MARK: - Type Methods

    static func createUser(with name: String) -> User {
        User(name: name)
    }

}

We can confirm that createUser(with:) is a type method by calling it on the User struct.

let john = User.createUser(with: "John")

As the name suggests, a type method can only be called on the type that defines the type method. The compiler throws an error if we try to call createUser(with:) on a User instance.

A type method cannot be called on an instance of the type.

What Are Class Methods in Swift?

The static keyword isn't the only option you have to declare type methods. Let's start with a clean slate and define a class with name Book. The Book class has two properties, title of type String and author of type String. It defines an initializer to create a Book instance.

class Book {

    // MARK: - Properties

    let title: String
    let author: String

    // MARK: - Initialization

    init(title: String, author: String) {
        self.title = title
        self.author = author
    }

}

We can use the static keyword to add a type method to Book. The favorites() method is a type method that returns an array of Book instances.

class Book {

    // MARK: - Properties

    let title: String
    let author: String

    // MARK: - Initialization

    init(title: String, author: String) {
        self.title = title
        self.author = author
    }

    // MARK: - Type Methods

    static func favorites() -> [Book] {
        [
            Book(title: "LOTR", author: "Tolkien")
        ]
    }

}

Book.favorites()

We can also create a type method using the class keyword. Let's add another type method, moreFavorites(). This time we use the class keyword.

class Book {

    // MARK: - Properties

    let title: String
    let author: String

    // MARK: - Initialization

    init(title: String, author: String) {
        self.title = title
        self.author = author
    }

    // MARK: - Type Methods

    static func favorites() -> [Book] {
        [
            Book(title: "LOTR", author: "Tolkien")
        ]
    }

    class func moreFavorites() -> [Book] {
        [
            Book(title: "The Hobbit", author: "Tolkien")
        ]
    }

}

Book.favorites()
Book.moreFavorites()

The compiler doesn't throw any errors. It seems we can declare type methods using the static keyword as well as the class keyword. What is the difference? The difference becomes evident if we subclass the Book class. Take a look at this example.

class FantasyBook: Book {

    override static func favorites() -> [Book] {
        [
            Book(title: "The Silmarillion", author: "Tolkien")
        ]
    }

    override class func moreFavorites() -> [Book] {
        [
            Book(title: "The Book of Lost Tales", author: "Tolkien")
        ]
    }

}

The compiler doesn't like this. It throws an error because we attempt to override a static method in a subclass.

It isn't possible to override a static method in a subclass in Swift.

Static methods cannot be overridden by subclasses of the class that defines the static method. There is another important difference. Enum and structs don't support inheritance, which means that you can only use static methods to define a type method on an enum or a struct. In summary, use the static keyword for enums and structs or if subclasses of the class that defines the type method should not be allowed to override the type method. Use the class keyword if subclasses of the class should be allowed to override the type method.

Download Your Free Copy of
The Missing Manual
for Swift Development

The Guide I Wish I Had When I Started Out

Join 20,000+ Developers Learning About Swift Development

Download Your Free Copy