kotlin中数据类的流畅方法

时间:2017-05-21 14:41:14

标签: java kotlin fluent-interface

我们熟悉用于在java和其他编程语言中调用方法的流畅接口。例如:

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

这可以通过setter方法实现所需类型的返回对象。

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;
}

我正在尝试使用kotlin数据类,但遗憾的是我找不到覆盖setter方法的方法,在这些方法中我可以返回该对象的新实例。

当我尝试强制覆盖setter方法时出现编译器错误。 enter image description here

有关可以做什么的任何想法,以便我可以调用流畅的界面或至少改变setter的工作方式 可能是这样的

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

这样我就可以打电话了

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

3 个答案:

答案 0 :(得分:9)

如果除了Name之外不需要返回任何内容,您可以这样做:

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

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

或其他例子:

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

在传递给apply的函数内部(大括号内),this是调用的对象apply,这使得可以引用成员函数和属性,如firstName未编写name.firstName

如果你对此不满意:不可能让实际的setter返回一些东西,但是你当然可以定义一个具有不同名称的方法并使其返回一些东西。

答案 1 :(得分:4)

为了访问Kotlin中的属性,我们不使用getter和setter函数,虽然你可以覆盖他们的setter来给他们自定义行为,但你不能让他们返回任何东西,因为调用它们是一个assigment,这不是Kotlin的表达。例如,这不起作用:

data class Name(var firstName: String = "", var lastName: String  =  "") {
    fun withLastName(lastName: String): Name {
        this.lastName = lastName
        return this
    }
}

val name = Name(firstName = "Jane") 
name.withLastName("Doe").withLastName("Carter")

您可以做的是定义设置它们的其他方法,然后返回它们被调用的实例。例如:

setLastName

请注意,如果您将此方法命名为lastName,则在使用Java中的类时会遇到问题,因为setLastName属性已通过名为apply的方法可见当你编写Java代码时。

Kotlin中可能更常见的解决方案是使用标准库中的//This method will parse json data private void parseData(JSONArray array) { for (int i = 0; i < array.length(); i++) { if(i!=1){ //Creating the object Posts PostObj = new Posts(); JSONObject json; try { //Getting json json = array.getJSONObject(i); //Adding data to the object PostObj.setImageUrl(json.getString(Config.TAG_IMAGE_URL)); PostObj.setName(json.getString(Config.TAG_NAME)); ... } ... 替换流畅的构建器,正如Christian在答案中所描述的那样。

答案 2 :(得分:3)

感谢Zsmb13和Christin的答案,但是如果有人想使用不可变字段我还有另一个解决方案

data class Foo(val fooString: String = "", val fooInt: Int = 0) {
    fun increaseTwo() = copy(fooInt = fooInt + 2)
    fun increaseThree() = copy(fooInt = fooInt + 3)
}

你可以像这样使用它

println( Foo("foo",2).increaseTwo().increaseThree())

输出

Foo(fooString=foo, fooInt=7)