Вы определили Builder
как вложенный класс NutritionFacts
. Поскольку он статичен, для его существования не требуется экземпляр NutritionFacts
. Если бы он не был статичным (так называемый «внутренний класс»), для его существования требовался бы NutritionFacts. Кроме того, некоторые из ваших полей Builder будут скрывать определенные поля NutritionFact, но сейчас это не так.
Теперь, так как вы использовали этот вложенный класс thingie, вы не можете просто назвать его как Builder
. Вам придется называть это NutritionFacts.Builder
. Таким образом, когда вы извлекаете второй код new NutritionFacts.Builder(240, 8)
, вы получаете новый экземпляр Builder с размером обслуживания 240 и 8 порций. NutritionFacts еще не вступил в игру, он существует только для названия.
Этот вновь создаваемый экземпляр может быть назначен некоторой переменной или может использоваться немедленно, скажем, путем вызова некоторого метода для него. Это то, что вы делаете, а именно вы называете .calories(100)
на нем, который устанавливает поле калорий этого Строителя. Но если вы пойдете и посмотрите на этот метод, вы заметите, что он имеет тип возвращаемого значения Builder, и в итоге он возвращает this
. Ключевое слово this просто ссылается на текущий экземпляр: тот же самый Builder снова.
То же самое происходит для .sodium(35)
и .carbohydrate(27)
, после чего вы в конечном итоге вызываете .build()
на своем Builder. Посмотри на этот метод. Он вызывает конструктор NutritionFacts. Этот конструктор принимает экземпляр Builder в качестве аргумента, и наш Builder передает себя (снова с this
). Теперь мы наконец получаем экземпляр NutritionFacts, и он создается с использованием значений, которые были сохранены в экземпляре Builder.
Как сказал Джере, методы, которые устанавливают питательные вещества для Builder, используют подход цепочки методов для возврата объекта, к которому они были вызваны, так что несколько методов могут быть удобно объединены в одну строку. В действительности, ваш второй отрывок может быть написан так:
NutritionFacts.Builder builder = new NutritionFacts.Builder(240, 8);
builder.calories(100);
builder.sodium(35);
builder.carbohydrate(27);
NutritionFacts cocaCola = builder.build();