gpt4 book ai didi

java - 在 Java 中继承流利的 setter

转载 作者:太空狗 更新时间:2023-10-29 22:38:43 24 4
gpt4 key购买 nike

我最近看到一些使用这种语法的代码(amazon hadoop 代码)

Foo bar = new Foo().setX(10).setY(11);

我觉得这很好,所以我决定试一试。使我的 setX() 类型函数返回 Foo 而不是 void 并将 return this; 放入所有函数中。这很好用。直到我用继承来尝试它,它产生了一些奇怪的结果。

我将举一个具体的例子:我有两个类,Location 类有两个字段,x 和 y。另一个类 Location3D 继承自 Location 并添加了第三个字段 z。所有字段都使用上面描述的方法作为它们的 setter 。

现在我想创建一个新的 location3D 实例并设置它的字段,会发生什么

new Location3D().setZ(7).setY(6).setX(5)

工作时

new Location3D().setX(7).setY(6).setZ(5)

没有。

by 不起作用 我的意思是从 setY(6) 返回的是一个 Location 对象而不是 location3D 对象,因此没有 setZ() 方法!

经过这么长的介绍,我的问题是:这种形式的“setter stringing”是否可以在不强制调用者强制转换对象的情况下与继承一起使用?如果是怎么办?

而且我确定有一个比“setter stringing”更好的术语,它是什么?

最佳答案

正如您所指出的,new Location3D().setX(7).setY(6).setZ(5) 不起作用的原因是因为 setX()setY() 返回 Location 而不是 Location3D 的实例。

您可以通过向您的 Location 类添加泛型类型参数来使用泛型(尽管解决方案不是特别漂亮)来解决这个问题:

public class Location<T extends Location<T>> {
protected int x, y;

@SuppressWarnings("unchecked")
public T setX(int x) {
this.x = x;
return (T) this;
}

@SuppressWarnings("unchecked")
public T setY(int y) {
this.y = y;
return (T) this;
}
}

您的子类 Location3D 然后会将自己设置为泛型类型参数,以便父类(super class)返回 Location3D 的实例而不是 Location:

public class Location3D extends Location<Location3D> {
protected int z;

public Location3D setZ(int z) {
this.z = z;
return this;
}
}

不幸的是,据我所知,没有办法避免父类(super class)产生的警告,因此有 @SuppressWarnings("unchecked") 注释。

还值得注意的是,如果您定义子类时泛型类型参数是不同的类类型,那么您可能会遇到 ClassCastException,因此您应该在父类(super class)中记录该限制任何可能想要创建自己的子类的人。

最后,以您描述的方式将方法调用链接在一起通常称为 method chaining .您描述的 setter 方法的样式与 builder pattern 密切相关.

关于java - 在 Java 中继承流利的 setter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14105275/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com