Fluent methods for data class in kotlin

erluxman picture erluxman · May 21, 2017 · Viewed 12.5k times · Source

We are familiar with fluent interfaces for calling methods in java and other programming languages. For eg:

Picasso.with(this).load(url).into(imageView);

This is made possible by setter methods what return object of desired type.

public Picasso with(Context context)
{
    this.context = context;
    return this;
}

public X load(String url)
{
    this.url = url;
    return this;
}

public Y load(ImageView imageView)
{
    this.imageView = imageView;
    return this;
}

I am trying to do the same with kotlin data classes but sadly I could not find a way to override the setter methods in which I could return the new instance of that object.

I get compiler error when I try to forcefully override setter method. enter image description here

Any idea about what can be done so that I can call fluent interfaces or at least alter how the setter works may be like this

data class CorruptOfficeAccount(.....){
     override fun addCollectedFee(Long money) :CorruptOfficeAccount {
     this.money = money/5
    }
}

So that I can call

CorrutOfficeAccount(....).method1().addCollectedFee(20000).method3()

Answer

Christian Brüggemann picture Christian Brüggemann · May 21, 2017

If don't need to return anything but Name, you can just do it like this instead:

data class Name(var firstName: String, var lastName: String)

fun foo() {
    val name = ...
    name.apply {
        firstName = ...
        lastName = ...
    }
}

or another example:

CorrutOfficeAccount(....).apply {
    method1()
    addCollectedFee(20000)
    method3()
}

Inside the function (what's inside the curly braces) passed to apply, this is the object apply was called on, which makes it possible to refer to member functions and properties like firstName without writing name.firstName.

If you're not happy with this: It's not possible to make the actual setter return something, however you can of course just define a method with a different name and make that return something.