Classes
What you'll learn:
- declare a class with
initand explain why two names can lead to one instance; - understand that
leton a class fixes only the reference, not the instance itself; - inherit from a class, override methods and check types with
isandas?; - choose between a struct and a class and explain the choice in an interview.

Imagine a sheet of paper with a heading — a document. Two tags are tied to the sheet on long strings: one reads a, the other b. Pull either tag and you reach the same sheet.
Rewrite a line after following tag b, and when you follow tag a you see the new line. There is one sheet, and two strings lead to it.
Shared online documents work this way: you can send a link to the document to many people, the document stays one, and everyone sees anyone's edit.
In the structs theme, var b = a made a photocopy of the form, and the copy was filled in separately. A class works like a shared document. Let's see what it looks like in code:
class Document {
var title = "Plan"
}
var a = Document()
var b = a
b.title = "Final"
print(a.title) // FinalLet's go through the program line by line:
class Documentdeclares a class with one property,title. As in a struct, the property has a default value.var a = Document()creates an instance of the class — that sheet — and gives the nameaa tag to it.var b = adoes not create a second sheet. The namebgets a second tag to the same instance.b.title = "Final"rewrites the heading of the shared sheet.print(a.title)printsFinal: tagaleads to the same sheet, so the edit shows.
If Document were a struct, the program would print Plan: b would be a separate copy.
Why have such a type? Sometimes several parts of a program work with one and the same thing: a bank account, a game character, an open document. If each part gets its own copy, the changes drift apart. A class gives every part of the program one shared instance.
A reference instead of a copy
A class is a type that, like a struct, groups properties and methods, but is not copied on assignment. A class variable holds not the instance itself but a reference to it — that tag on a string. Assignment copies the reference, and the instance stays one. An instance of a class is also called an object.
A class is a reference type, like a closure. Structs, arrays, Int and String, on the other hand, are value types: for them, assignment copies the value itself.
The === operator checks whether two references lead to the same instance. It answers true only when the instance is one and the same, and the !== operator answers the opposite. They work only with classes: a struct has no reference to compare.
Click "Next step" and watch a.title and b.title: they change together because there is one instance. And c appears on its own.
1class Document {2 var title = "Plan"3}4 5var a = Document()6var b = a7b.title = "Final"8print(a.title)9print(a === b)10let c = Document()11print(c.title)12print(a === c)
Document() creates an instance, and a gets a reference to it.
Each call to Document() creates a new instance — a new sheet. So c has no link to a and b, and a === c answers false.
Here the sheet picture falls short. A real document can be copied with a button, but a class has no such button. var b = a always gives one more tag, and only a call to Document() creates a new sheet.
Interviewers often give a junior a program with a struct and ask what it prints if struct is replaced with class. The answer: a struct is copied on assignment, while a class instance stays shared, and an edit through one name is visible through the other.
A class and init
A struct gets a memberwise initializer by itself, for example Point(x: 1, y: 2). A class gets no memberwise initializer. If every property has a default value, the class has an empty init(): that is how we created Document().
If at least one property has no default value, you write init yourself:
class Account {
var owner: String
var balance = 0
init(owner: String) {
self.owner = owner
}
}
let anna = Account(owner: "Anna")
print(anna.owner, anna.balance) // Anna 0Let's see how the account is created:
ownerhas no default value, soinitmust set it.init(owner: String)takes the owner as a parameter, andself.owner = ownerputs it into the property of the new instance.balanceis already0, andinitleaves it alone.Account(owner: "Anna")calls thisinit, andprintprintsAnna 0.
Common mistake
A class is declared like a struct: with a property that has no default value and no init.
class Profile {
var name: String // ✗
}error: class 'Profile' has no initializersThe program does not compile: a class has no memberwise initializer, so nothing can set name. Below the error, the compiler also names the cause — the property name without an initial value. There are two ways to fix it:
- give the property a default value:
var name = ""; - write
init(name: String), as inAccount.
Key points
- A class is declared with
class; a class variable holds a reference to an instance, not the instance itself. var b = acopies the reference:aandblead to one instance, and an edit through one name is visible through the other.===checks whether it is the same instance; each call such asDocument()creates a new one.- A class gets no memberwise initializer: if a property has no default value, the class needs its own
init.