首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >生成UI组件

生成UI组件
EN

Stack Overflow用户
提问于 2010-02-04 13:39:32
回答 3查看 246关注 0票数 1

我花了几天的时间试图弄清楚是否可能,但我失败了,但也许它是可能的(我认为它应该是可能的)。

假设我们有一些类似于Swing层次结构的UI组件,我们将使用fluent接口Fluent Interfaces

代码语言:javascript
复制
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();
} 

有没有可能,使用泛型就能写出这样的东西?

代码语言:javascript
复制
new TitledPanel().setName("panel").setTitle("Title);

为了能够链接这些调用,setName应该返回一个TitledPanel而不是Component。

这只是一个简单的例子,但是我的想法是,一旦我有一个T类型的对象,调用超类的任何流畅的方法来返回T类型。

编辑1:我忘了排除覆盖方法和返回协变类型的部分:)如果确实可能的话,我只想要普通的泛型。

EN

回答 3

Stack Overflow用户

发布于 2010-02-04 14:02:07

首先,我建议只使用set方法,并删除set。

您可以使用协变返回类型,但这意味着覆盖每个派生类中的所有方法。然而,它确实涉及到许多非常繁琐的代码。

代码语言:javascript
复制
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参数,如枚举,可以使实现更容易,但是客户端代码可能需要在声明中添加<?>

代码语言:javascript
复制
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;
    }
}

另一种方法是使用双括号习惯用法。

代码语言:javascript
复制
new TitledPane() {{
    name("panel");
    title("Title");
}}
票数 2
EN

Stack Overflow用户

发布于 2010-02-04 14:01:58

我真的不确定你是否可以用泛型来实现这一点。你可以这样做:

代码语言:javascript
复制
public abstract class Component {

private String name;

public Component setName(String name) {
    this.name = name;
    return this;
}

public String getName() {
    return name;
}

}

代码语言:javascript
复制
public abstract class Panel extends Component {

}

代码语言:javascript
复制
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");可以工作了

票数 1
EN

Stack Overflow用户

发布于 2010-02-04 14:03:44

在你的TiltedPanel中(顺便说一句,它不能是抽象的,如果你想更新一个),你可以覆盖Component中的抽象方法并改变返回类型。返回类型不是方法签名的一部分,因此您可以使用不同的返回类型来实现它:

代码语言:javascript
复制
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;
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2197553

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档