生成 UI 组件

发布于 2024-08-20 08:45:43 字数 895 浏览 5 评论 0原文

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

假设我们有一些与 Swing 层次结构类似的 UI 组件 + 我们将使用流畅的界面 流畅的界面:

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:我忘记排除覆盖方法并返回协变的部分类型 :) 如果确实可能的话,我只想要普通的泛型。

I was trying for days to figure out if is possible, I failed but maybe it is be possible(I think it should be possible).

Let's say we have a few UI components similar with Swing hierarchies + we will use fluent interfaces 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();
} 

Is it possible, using generic to be able to write something like that?

new TitledPanel().setName("panel").setTitle("Title);

setName should return a TitledPanel instead of Component to be able to link those calls.

This is just a simple example, but the idea is once I have an object of type T any call to any fluent method of a superclass to return type T.

Edit 1: I forgot to exclude the part with overriding the methods and returning a covariant types :) I want just plain generics, if it is possible indeed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

眼眸 2024-08-27 08:45:43

首先,我建议仅使用 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");
}}

Firstly I suggest using only set methods, and dropping the set.

You can use covariant return types, but this means overriding every method in each derived class. However, it does involve a lot of very tedious code.

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

Adding a generic THIS parameter, as enum, makes the implementation easier, but client code may need to add a <?> in declarations.

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

An alternative is to use the Double Brace Idiom.

new TitledPane() {{
    name("panel");
    title("Title");
}}
他是夢罘是命 2024-08-27 08:45:43

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

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"); 就可以工作了

I am not really sure if you could achieve this with generics. What you can do is something like this:

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

}

Now new TitledPanel().setName("panel").setTitle("Title"); will work

云巢 2024-08-27 08:45:43

在你的 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;
    }
}

In your TiltedPanel (which can't be abstract by the way, if you want to new one up), you can override the abstract methods in Component and change the return type. The return type is not part of the method signature, so you can implement it with a different return type:

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;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文