Menu
Coddy logo textTech

Secondary Constructors

Part of the Object Oriented Programming section of Coddy's Kotlin journey. Lesson 5 of 57.

A class can offer extra ways of being created with secondary constructors, declared with constructor. Each one must call the primary constructor with this(...):

class Temperature(val celsius: Double) {
    constructor(fahrenheit: Int) : this((fahrenheit - 32) * 5 / 9.0)
}

Inside main:

println(Temperature(20.0).celsius)
println(Temperature(212).celsius)

Output:

20.0
100.0

Default arguments often make secondary constructors unnecessary. Prefer one primary constructor with defaults, and use a secondary constructor when the input has a different shape, such as text to parse:

class Color(val r: Int, val g: Int, val b: Int) {
    constructor(gray: Int) : this(gray, gray, gray)
    constructor(hex: String) : this(hex.substring(0, 2).toInt(16), hex.substring(2, 4).toInt(16), hex.substring(4, 6).toInt(16))

    fun label() = "rgb($r, $g, $b)"
}

Inside main:

println(Color(128).label())
println(Color("FF8000").label())

Output:

rgb(128, 128, 128)
rgb(255, 128, 0)

The primary constructor and its init blocks run first, then the body of the secondary constructor:

class Log(val name: String) {
    init { println("primary: $name") }
    constructor(id: Int) : this("log-$id") {
        println("secondary: $id")
    }
}

Inside main:

Log(7)

Output:

primary: log-7
secondary: 7

Constructors must work with every overload unambiguously. Two constructors with the same parameter types are not allowed, and a call that could match several constructors does not compile.

class Size(val w: Int, val h: Int) {
    constructor(side: Int) : this(side, side)   // Size(3) -> a square
    // constructor(w: Int) : this(w, 1)        // error: same signature as above
}
challenge icon

Challenge

Easy

Complete the class Duration(val seconds: Int) with a secondary constructor (minutes: Int, seconds: Int) and another one that takes text like 1:30 or 2:05:10 (hours:minutes:seconds). Add format(), which returns h:mm:ss with two-digit minutes and seconds.

The supplied code reads durations as text with one or two colons, creates each with the text constructor and prints format(), then prints total and the formatted sum.

Your code goes in Duration.kt. Main.kt holds the supplied input/output code and cannot be edited.

Try it yourself

fun main() {
    // Supplied input/output code: keep it as it is
    val input = generateSequence(::readLine).toList()
    var total = 0
    for (line in input) {
        val d = Duration(line)
        println(d.format())
        total += d.seconds
    }
    println("total " + Duration(total).format())
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming

Practice on your own: Kotlin playground