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

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

Subclassing a subclass of a (generic) builder

问题

  1. public class StackOverflow {
  2. public static class Builder<T extends Builder<T>> {
  3. public Builder() {}
  4. public T doA() {
  5. System.out.println("A");
  6. return (T) this;
  7. }
  8. }
  9. public static class BuilderSubclass<T extends BuilderSubclass<T>>
  10. extends Builder<BuilderSubclass<T>> {
  11. public BuilderSubclass() {}
  12. public T doB() {
  13. System.out.println("B");
  14. return (T) this;
  15. }
  16. }
  17. public static class BuilderSubclassSubclass
  18. extends BuilderSubclass<BuilderSubclassSubclass> {
  19. public BuilderSubclassSubclass() {}
  20. public BuilderSubclassSubclass doC() {
  21. System.out.println("C");
  22. return this;
  23. }
  24. }
  25. }

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:

  1. StackOverflow.BuilderSubclassSubclass builder = new StackOverflow.BuilderSubclassSubclass();
  2. builder.doA();
  3. builder.doB();
  4. builder.doC();

In which case the code becomes:

  1. public class StackOverflowBatchHelperFunctions {
  2. public static class Builder {
  3. public Builder() {
  4. }
  5. public void doA() {
  6. System.out.println("A");
  7. }
  8. }
  9. public static class BuilderSubclass extends Builder {
  10. public BuilderSubclass() {
  11. super();
  12. }
  13. public void doB() {
  14. System.out.println("B");
  15. }
  16. }
  17. public static class BuilderSubclassSubclass extends BuilderSubclass {
  18. public BuilderSubclassSubclass() {
  19. super();
  20. }
  21. public void doC() {
  22. System.out.println("C");
  23. }
  24. }
  25. }

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

  1. <details>
  2. <summary>英文:</summary>
  3. 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:
  4. ```java
  5. public class StackOverflow {
  6. public static class Builder&lt;T extends Builder&lt;T&gt;&gt; {
  7. public Builder() {}
  8. public T doA() {
  9. System.out.println(&quot;A&quot;);
  10. return (T) this;
  11. }
  12. }
  13. public static class BuilderSubclass &lt;T extends BuilderSubclass&lt;T&gt;&gt;
  14. extends Builder&lt;BuilderSubclass&lt;T&gt;&gt; {
  15. public BuilderSubclass() {}
  16. public T doB() {
  17. System.out.println(&quot;B&quot;);
  18. return (T) this;
  19. }
  20. }
  21. public static class BuilderSubclassSubclass
  22. extends BuilderSubclass&lt;BuilderSubclassSubclass&gt; {
  23. public BuilderSubclassSubclass() {}
  24. public BuilderSubclassSubclass doC() {
  25. System.out.println(&quot;C&quot;);
  26. return this;
  27. }
  28. }
  29. }

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:

  1. StackOverflow.BuilderSubclassSubclass builder = new StackOverflow.BuilderSubclassSubclass();
  2. builder.doA();
  3. builder.doB();
  4. builder.doC();

In which case the code becomes:

  1. public class StackOverflowBatchHelperFunctions {
  2. public static class Builder {
  3. public Builder() {
  4. }
  5. public void doA() {
  6. System.out.println(&quot;A&quot;);
  7. }
  8. }
  9. public static class BuilderSubclass extends Builder {
  10. public BuilderSubclass() {
  11. super();
  12. }
  13. public void doB() {
  14. System.out.println(&quot;B&quot;);
  15. }
  16. }
  17. public static class BuilderSubclassSubclass extends BuilderSubclass {
  18. public BuilderSubclassSubclass() {
  19. super();
  20. }
  21. public void doC() {
  22. System.out.println(&quot;C&quot;);
  23. }
  24. }
  25. }

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:

确定