Kotlin/Swift Comparison: Classes
A look at the differences between Kotlin and Swift classes
Andy Brown · 28/07/2024 · 3 min read
Let’s look at some of the differences between classes in Swift and Kotlin. We’re going to create a Vehicle
class and build from there.
Initialisation of a class:
Here’s the basic structure for initialising a class.
Swift:
In Swift you provide an initialiser.
public final class Vehicle {
let make: String
let model: String
let year: Int
let isElectric: Bool
var mileage: Int
init(
make: String,
model: String,
year: Int,
isElectric: Bool,
mileage: Int = 0
) {
self.make = make
self.model = model
self.year = year
self.isElectric = isElectric
self.mileage = mileage
}
}
Remarks:
- Notice the default value for
mileage
. - Notice you have to declare
public
andfinal
to make the class public and prevent inheritance. -
let
is read-only. -
var
is a writeable property.
Kotlin:
In Kotlin you provide a constructor. It’s a bit more concise since you declare and initialise properties all within the constructor.
class Vehicle(
val make: String,
val model: String,
val year: Int,
val isElectric: Boolean,
var mileage: Int = 0, // Notice the trailing comma
) {
}
Remarks:
- Notice the default value for
mileage
. - Notice the trailing comma, which makes version-control diffs cleaner and it’s easier to reorder elements. This is optional.
- Public is the default visibility so there’s no need to declare it.
- All classes are
final
by default (that is, they don’t allow inheritance) so there’s no need to declare it. -
val
is a read-only property. -
var
is a writable property.
Methods
Now let’s add a method to drive the car. Pretty much identical.
Swift
func drive(miles: Int) {
mileage += miles
}
Kotlin
fun drive(miles: Int) {
mileage += miles
}
Private Properties
Let’s add a private property to store the car’s serial number. Not much of note here as it’s similar to regular properties.
Swift
public final class Vehicle {
// Other properties as before
private let serialNumber: String
init(
// As before
serialNumber: String
) {
// As before
self.serialNumber = serialNumber
}
}
Kotlin
class Vehicle(
// Constructor as before
private val serialNumber: String,
)
Private (Set) Properties
Ideally, if we provide a method for driving we wouldn’t also allow the user to fiddle with the odometer directly; we need to make the mileage public for read only.
Swift
private (set) var mileage: Int
Kotlin
It’s a bit trickier in Kotlin because there’s no way to call out private set in the constructor shorthand. In that instance we need to move mileage
out of in constructor and add it as a property of the class with a default value like this:
var mileage: Int = 0
private set
Computed Properties
Let’s expand our class to include a computed property for determining if the car is new.
Swift
var isNew: Bool {
mileage == 0
}
Remarks:
- Notice the omission of the
return
keyword.
Kotlin
val isNew: Boolean
get() {
return mileage == 0
}
This can be written in the more concise way:
val isNew: Boolean get() = mileage == 0
Convienience Initialisers
Swift
In Swift you provide a convenience initialiser:
convenience init(
make: String,
model: String,
year: Int,
serialNumber: String
) {
self.init(make: make, model: model, year: year, isElectric: false, serialNumber: serialNumber)
}
Kotlin
In Kotlin you provide a secondary constructor:
class Vehicle(
// Constructor as before
) {
constructor(make: String, model: String, year: Int, serialNumber: String)
: this(make, model, year, false, serialNumber)
}
Reference Semantics
Classes are passed by reference in Swift and Kotlin, meaning that when you update or copy a class, you’re updating or copying the underlying reference rather than the object itself. Here’s how the two compare:
Swift
let myFirstCar = Vehicle(make: "Ford", model: "Fiesta", year: 2008, isElectric: false, serialNumber: "123")
myFirstCar.drive(miles: 100)
print(myFirstCar.mileage) // Output: 100
// I sell the car to someone else, transferring ownership.
let newOwnersCar = myFirstCar
print(newOwnersCar.mileage) // Output: 100
newOwnersCar.drive(miles: 200)
print(myFirstCar.mileage) // Output: 300
print(newOwnersCar.mileage) // Output: 300
Kotlin
val myFirstCar = Vehicle(make = "Ford", model = "Fiesta", year = 2008, isElectric = false, serialNumber = "123")
myFirstCar.drive(100)
println(myFirstCar.mileage) // Output: 100
// I sell the car to someone else, transferring ownership.
val newOwnersCar = myFirstCar
println(newOwnersCar.mileage) // Output: 100
newOwnersCar.drive(200)
println(myFirstCar.mileage) // Output: 300
println(newOwnersCar.mileage) // Output: 300
Remarks:
- Notice that you don’t include the parameter name for the drive method.
Discussions
Login to Post Comments