我花了几天的时间试图弄清楚是否可能,但我失败了,但也许它是可能的(我认为它应该是可能的)。
假设我们有一些类似于Swing层次结构的UI组件,我们将使用fluent接口Fluent Interfaces
public abstract class Component {
...
public abstract Component setName(String name);
public abstract String getName();
...
}
public abstract class Panel extends Component {
....
}
public abstract class TitledPanel extends Panel {
....
public abstract TitledPanel setTitle(String title);
public abstract String getTitle();
} 有没有可能,使用泛型就能写出这样的东西?
new TitledPanel().setName("panel").setTitle("Title);为了能够链接这些调用,setName应该返回一个TitledPanel而不是Component。
这只是一个简单的例子,但是我的想法是,一旦我有一个T类型的对象,调用超类的任何流畅的方法来返回T类型。
编辑1:我忘了排除覆盖方法和返回协变类型的部分:)如果确实可能的话,我只想要普通的泛型。
发布于 2010-02-04 14:02:07
首先,我建议只使用set方法,并删除set。
您可以使用协变返回类型,但这意味着覆盖每个派生类中的所有方法。然而,它确实涉及到许多非常繁琐的代码。
public abstract class Component {
...
public Component name(String name) {
this.name = name;
return this
}
}
public abstract class Panel extends Component {
...
public Panel name(String name) {
super.name(name);
return this;
}
}添加一个通用的THIS参数,如枚举,可以使实现更容易,但是客户端代码可能需要在声明中添加<?>。
public abstract class Component<THIS extends Component<THIS>> {
...
protected abstract THIS getThis();
...
public THIS name(String name) {
this.name = name;
return this
}
}
public abstract class Panel<THIS extends Panel<THIS>> extends Component<THIS> {
...
}
public class TitledPanel extends Panel<TitledPanel> {
...
public TitledPanel getThis() {
return this;
}
}另一种方法是使用双括号习惯用法。
new TitledPane() {{
name("panel");
title("Title");
}}发布于 2010-02-04 14:01:58
我真的不确定你是否可以用泛型来实现这一点。你可以这样做:
public abstract class Component {
private String name;
public Component setName(String name) {
this.name = name;
return this;
}
public String getName() {
return name;
}}
public abstract class Panel extends Component {}
public class TitledPanel extends Panel {
private String title;
public TitledPanel setTitle(String title) {
this.title = title;
return this;
}
@Override
public TitledPanel setName(String name) {
super.setName(name);
return this;
}
public String getTitle() {
return title;
}}
现在new TitledPanel().setName("panel").setTitle("Title");可以工作了
发布于 2010-02-04 14:03:44
在你的TiltedPanel中(顺便说一句,它不能是抽象的,如果你想更新一个),你可以覆盖Component中的抽象方法并改变返回类型。返回类型不是方法签名的一部分,因此您可以使用不同的返回类型来实现它:
public class Test
{
public static void main(String[] args)
{
TiltedPanel p = new TiltedPanel().setName("panel").setTitle("title");
System.out.println("name = " + p.getName());
System.out.println("title = " + p.getTitle());
}
}
abstract class Component
{
public abstract Component setName(String name);
public abstract String getName();
}
abstract class Panel extends Component
{
}
class TiltedPanel extends Panel
{
private String title;
private String name;
public TiltedPanel setName(String name)
{
this.name = name;
return this;
}
public String getName()
{
return this.name;
}
public TiltedPanel setTitle(String title)
{
this.title = title;
return this;
}
public String getTitle()
{
return this.title;
}
}https://stackoverflow.com/questions/2197553
复制相似问题