继承泛型构建器的子类的子类

huangapple go评论77阅读模式
英文:

Subclassing a subclass of a (generic) builder

问题

public class StackOverflow {
    public static class Builder<T extends Builder<T>> {
        public Builder() {}

        public T doA() {
            System.out.println("A");
            return (T) this;
        }
    }
    
    public static class BuilderSubclass<T extends BuilderSubclass<T>> 
            extends Builder<BuilderSubclass<T>> {
        
        public BuilderSubclass() {}

        public T doB() {
            System.out.println("B");
            return (T) this;
        }
    }

    public static class BuilderSubclassSubclass
            extends BuilderSubclass<BuilderSubclassSubclass> {

        public BuilderSubclassSubclass() {}

        public BuilderSubclassSubclass doC() {
            System.out.println("C");
            return this;
        }
    }
}

I would like to do something like this:
new StackOverflow.BuilderSubclassSubclass().doA().doC().doB()

However, when I call new StackOverflow.BuilderSubclassSubclass().doA(), the returned object is not a BuilderSubclassSubclass but a BuilderSubclass<BuilderSubclassSubclass>. I know why this is the case: Builder's generic type is BuilderSubclass<BuilderSubclassSubclass> which is assigned in the class signature of BuilderSubclass.

Any ideas on how I can avoid this problem?

Update: I guess I could avoid using the builder pattern, and instead call the functions like this:

StackOverflow.BuilderSubclassSubclass builder = new StackOverflow.BuilderSubclassSubclass();
builder.doA();
builder.doB();
builder.doC();

In which case the code becomes:

public class StackOverflowBatchHelperFunctions {
    public static class Builder {

        public Builder() {
        }

        public void doA() {
            System.out.println("A");
        }
    }

    public static class BuilderSubclass extends Builder {
        public BuilderSubclass() {
            super();
        }

        public void doB() {
            System.out.println("B");
        }
    }

    public static class BuilderSubclassSubclass extends BuilderSubclass {
        public BuilderSubclassSubclass() {
            super();
        }

        public void doC() {
            System.out.println("C");
        }
    }
}

However, I think this is less "pretty", so I would still love to see an answer to the initial problem.


<details>
<summary>英文:</summary>

I&#39;m trying to implement a builder object with multi-level inheritance. I took some inspiration from https://stackoverflow.com/questions/17164375/subclassing-a-java-builder-class and this is my (simplified) code:

```java
public class StackOverflow {
    public static class Builder&lt;T extends Builder&lt;T&gt;&gt; {
        public Builder() {}

        public T doA() {
            System.out.println(&quot;A&quot;);
            return (T) this;
        }
    }
    
    public static class BuilderSubclass &lt;T extends BuilderSubclass&lt;T&gt;&gt; 
            extends Builder&lt;BuilderSubclass&lt;T&gt;&gt; {
        
        public BuilderSubclass() {}

        public T doB() {
            System.out.println(&quot;B&quot;);
            return (T) this;
        }
    }

    public static class BuilderSubclassSubclass
            extends BuilderSubclass&lt;BuilderSubclassSubclass&gt; {

        public BuilderSubclassSubclass() {}

        public BuilderSubclassSubclass doC() {
            System.out.println(&quot;C&quot;);
            return this;
        }
    }
}

I would like do something like this:
new StackOverflow.BuilderSubclassSubclass().doA().doC().doB()

However, when I call new StackOverflow.BuilderSubclassSubclass().doA(), the returned object is not a BuilderSubclassSubclass but a BuilderSubclass&lt;BuilderSubclassSubclass&gt;. I know why this is the case: Builder's generic type is BuilderSubclass&lt;BuilderSubclassSubclass&gt; which is assigned in the class signature of BuilderSubclass.

Any ideas on how I can avoid this problem?

Update: I guess I could avoid using the builder pattern, and instead call the functions like this:

StackOverflow.BuilderSubclassSubclass builder = new StackOverflow.BuilderSubclassSubclass();
builder.doA();
builder.doB();
builder.doC();

In which case the code becomes:

public class StackOverflowBatchHelperFunctions {
    public static class Builder {

        public Builder() {
        }

        public void doA() {
            System.out.println(&quot;A&quot;);
        }
    }

    public static class BuilderSubclass extends Builder {
        public BuilderSubclass() {
            super();
        }

        public void doB() {
            System.out.println(&quot;B&quot;);
        }
    }

    public static class BuilderSubclassSubclass extends BuilderSubclass {
        public BuilderSubclassSubclass() {
            super();
        }

        public void doC() {
            System.out.println(&quot;C&quot;);
        }
    }
}

However I think this is less "pretty", so I would still love to see an answer to the initial problem.

答案1

得分: 0

你应该将 public static class BuilderSubclass&lt;T extends BuilderSubclass&lt;T&gt;&gt; extends Builder&lt;BuilderSubclass&lt;T&gt;&gt; 替换为 public static class BuilderSubclass&lt;T extends BuilderSubclass&lt;T&gt;&gt; extends Builder&lt;T&gt;

英文:

You should replace public static class BuilderSubclass&lt;T extends BuilderSubclass&lt;T&gt;&gt; extends Builder&lt;BuilderSubclass&lt;T&gt;&gt; with public static class BuilderSubclass&lt;T extends BuilderSubclass&lt;T&gt;&gt; extends Builder&lt;T&gt;.

huangapple
  • 本文由 发表于 2020年4月8日 14:36:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/61094648.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定