Can I have an abstract builder class in java with method chaining without doing unsafe operations?

后端 未结 3 2057
一个人的身影
一个人的身影 2021-01-31 18:08

I\'m trying to have an abstract base class for some builder classes so I can easily reuse code between the Builder implementations. I want my builders to support method chaining

相关标签:
3条回答
  • 2021-01-31 18:30

    One alternative is not to use generics, but use overrides:

    abstract class AbstractBuilder
    {
       public AbstractBuilder foo()
       {
          // set some property
          return this;
       }
    }
    
    class TheBuilder extends AbstractBuilder
    {
       @Override public TheBuilder foo()
       {
          super.foo(); return this;
       }
       public TheBuilder bar()
       {
          // set some other property
          return this;
       }
    
       public Object build()
       {
          return new Object();
       }
    }
    
    0 讨论(0)
  • 2021-01-31 18:39

    You want to declare T as extends AbstractBuilder<T> in AbstractBuilder.

    Use an abstract protected method to get this of type T.

    abstract class AbstractBuilder<T extends AbstractBuilder<T>> {
        protected abstract T getThis();
    
        public T foo() {
            // set some property
            return getThis();
        }
    }
    
    
    class TheBuilder extends AbstractBuilder<TheBuilder> {
        @Override protected TheBuilder getThis() {
            return this;
        }
        ...
    }
    

    Alternatively, drop the generic type parameter, rely on covariant return types and make the code cleaner for clients (although usually they would be using TheBuilder rather than the largely implementation detail of the base class), if making the implementation more verbose.

    0 讨论(0)
  • 2021-01-31 18:52

    This should help:

    abstract class AbstractBuilder<T extends AbstractBuilder<?>>
    {
       public AbstractBuilder<T> foo()
       {
          // set some property
          return (AbstractBuilder<T>) this;
       }
    
       abstract AbstractBuilder<T> bar();
       abstract Object build();
    }
    
    0 讨论(0)
提交回复
热议问题