2017-02-04 5 views
1

Я моделирую что-то в Java и используя шаблон Builder. В ряде случаев некоторые общие члены определяются в родительском, с дополнительными членами дочерних элементов, которые наследуются от родителя. Примером может служить следующее:Наследование и статические вложенные классы Java

public class Parent { 
    private Integer age; 

    static class ParentBuilder { 
     private Integer age; 

     public ParentBuilder age(Integer age) { 
      this.age = age; 
      return this; 
     } 
    } 
} 

и

public class Child extends Parent { 

    private Integer height; 

    static class ChildBuilder extends Parent.ParentBuilder { 
     private Integer height; 

     public ChildBuilder height(Integer height) { 
      this.height = height; 
      return this; 
     } 

     public Child build() { 
      return new Child(this); 
     } 
    } 

    public static ChildBuilder builder() { 
     return new ChildBuilder(); 
    } 

    public Child(ChildBuilder b) { 
     this.height = b.height; 
    } 
} 

Если я пытаюсь сделать что-то вроде

Child child = Child.builder() 
    .age(18) 
    .height(150) 
    .build(); 

Я получаю ошибку, пытаясь скомпилировать:

Main.java:6: error: cannot find symbol 
     .height(150) 
     ^
symbol: method height(int) 
location: class ParentBuilder 

Если я удалю .height(150), я тогда ge t та же ошибка на .build(). Кажется, у меня есть фундаментальное непонимание наследования со статическими вложенными классами.

Почему, когда Child.builder() возвращает ChildBuilder, компилятор жалуется, что метод не находится в ParentBuilder? Есть ли способ сделать эту работу, как я пытаюсь, используя наследование вместе с этим шаблоном Builder, чтобы разрешить определение общих членов в родительском и других дочерних элементах?

+4

Это 'age', который возвращает' ParentBuilder', следовательно, почему существует ошибка complation пытаясь вызвать 'height'. Посмотрите на http://stackoverflow.com/questions/21086417/builder-pattern-and-inheritance или http://stackoverflow.com/questions/17164375/subclassing-a-java-builder-class – Tunaki

+0

Я бы использовал только Integer 'вместо' int', если a) значение может быть «null» или b) у вас не было выбора –

+0

Здесь нет [tag: inner-classes], только статические вложенные классы, которые по определению не являются внутренними. – EJP

ответ

1

Вы можете заставить его работать с дженериков

static class ParentBuilder<B extends ParentBuilder<B>> { 
    public B age(Integer age) { 
     this.age = age; 
     return (B) this; 
    } 
} 

static class ChildBuilder extends Parent.ParentBuilder<ChildBuilder> { 
    private Integer height; 

    public ChildBuilder height(Integer height) { 
     this.height = height; 
     return this; 
    } 

    public Child build() { 
     return new Child(this); 
    } 
} 

Таким образом age возвратит ChildBuilder для ChildBuilder

+0

Спасибо, в сочетании с ссылкой @ Tunaki. Думаю, у меня это есть. Нужно использовать 'this' для (B) или использовать шаблон' getThis() 'однако. – razor

+0

@razor да. Вам нужен актерский состав. Обновлен ответ. –

 Смежные вопросы

  • Нет связанных вопросов^_^