Ben Woodworth
Ben Woodworth

Reputation: 385

When creating an interface in Kotlin, does it matter if properties have get/set?

In a Kotlin interface, does it matter if properties are declared with empty get/set statements?

For instance...

interface ExampleInterface {
    // These...
    val a: String
        get
    var b: String
        get
        set

    // ...compared to these...
    val c: String
    var d: String
}

I'm having a hard time noticing a difference.

When implementing the interface, it doesn't seem to matter if I use getters/setters for the properties, or if I set the value directly.

When accessing these through java, the val's both have getters, and the var's both have getters and setters.

public void javaMethod(ExampleInterface e) {
    e.getA();

    e.getB();
    e.setB();

    e.getC();

    e.getD();
    e.setD();
}

Upvotes: 11

Views: 4795

Answers (1)

hotkey
hotkey

Reputation: 147901

The property declarations in your example are identical, get and set can be safely removed from there, because, as you correctly noted, the accessors are generated anyway. The syntax with get and set can, however, be used to provide an accessor implementation or to restrict its visibility.

  • Providing implementation:

    interface ExampleInterface {
        var b: String
            get() = ""
            set(value) { }
    }
    

    This example shows a default implementation of a property declared in an interface. This property can still be overriden inside the interface implementations.

    class Example {
        var b: String = ""
            get() = "$field$field"
    }
    

    Here, get() = ... overrides the default getter behavior of a property with a backing field, whereas set is not mentioned, thus it behaves normally.

  • Visibility restriction:

    class Example {
         var s: String = "s"
             private set
    }
    

    In this example, the setter visibility is private. The visibility of get is always the same to the visibility of the property, so there's no need to specify it separately. Interfaces cannot declare private members.

    abstract class Example { 
        abstract var b: String
            protected set // Restrict visibility
    }
    

    The setter of this property is restricted to this class and its subclasses. Interfaces cannot declare protected members.

Of course, an accessor implementation can be combined with visibility restriction:

class Example {
    var s: String = "abc"
        private set(value) { if (value.isNotEmpty()) field = value }
}

See also:

Upvotes: 13

Related Questions