本文介绍了Java Builder类的泛型层次结构:如何使build()返回正确的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的课程结构:

                Stuff
              /       \
   Food
     |   
   FastFood                  Drink
     |                        |
   Pizza                    Juice
  /     \                   /    \
 |     SicilianPizza       |    OrangeJuice
 |                      AppleJuice
CaliforniaPizza

我可以使用以下构建器创建比萨饼和果汁对象:

I can create pizza and juice objects using builders like this:

CaliforniaPizza californiaPizze = CaliforniaPizza.builder(2)
                .addTopping("Tomatoes").addOlives(true).build();
        SicilianPizza sicilianPizza = SicilianPizza.builder(1)
                .addTopping("Bacon").addCheese(false).build();

        AppleJuice appleJuice = AppleJuice.builder(40)
                .setPrice(120).setAlcoholVolume(0).setAppleColor("yellow").build();
        OrangeJuice orangeJuice = OrangeJuice.builder(35).setOrangeSize(8).build();

构建器的每个setter方法都返回正确的对象:

Every setter method of the builder returns correct object:

我想创建一个接受 FastFood的方法.Builder 对象,并使用它创建 FastFood 对象,该对象会将其传递给另一种方法:

I'd like to create a method that would accept a FastFood.Builder object and use it to create a FastFood object that would pass it to another method:

public void makeFat(FastFood fastFood)  {...}

但是我不能:setter方法不返回 FastFood ,而是返回其父项:

But I can't: setter methods don't return FastFood, but rather its parents:

我的仿制药有问题吗?

Is there something wrong with my generics? How could that be accomplished?

package pizza;

import java.util.*;

class TestStuff {
    public static void main(String[] args) {
        CaliforniaPizza californiaPizze = CaliforniaPizza.builder(2)
                .addTopping("Tomatoes").addOlives(true).build();
        SicilianPizza sicilianPizza = SicilianPizza.builder(1)
                .addTopping("Bacon").addCheese(false).build();

        AppleJuice appleJuice = AppleJuice.builder(40)
                .setPrice(120).setAlcoholVolume(0).setAppleColor("yellow").build();
        OrangeJuice orangeJuice = OrangeJuice.builder(35).setOrangeSize(8).build();
    }

    public FastFood testFood(FastFood.Builder fastFoodBuilder)  {
       //return  fastFoodBuilder.setMealType("fd").addOlives(true).setPrice(20).build();
    }

    public void makeFat(FastFood fastFood)  {}
}



abstract class Stuff {
    protected double price;

    protected Stuff()  {}

    protected abstract class Builder<T extends Builder<T>>  {
        protected abstract Stuff build();
        protected abstract T self();

        public T setPrice(double price)  {
            Stuff.this.price = price;
            return self();
        }
    }
}

abstract class Food extends Stuff {
    protected String mealType; //breakfast/dinner/etc

    protected Food()  {}

    public abstract class Builder<T extends Builder<T>> extends Stuff.Builder<T> {
        protected abstract Food build();
        protected abstract T self();

        public T setMealType(String mealType)  {
            Food.this.mealType = mealType;
            return self();
        }
    }
}

abstract class FastFood extends Food  {
    protected int harm;

    protected FastFood() {}

    public abstract class Builder<T extends Builder<T>> extends Food.Builder<T> {
        protected abstract FastFood build();
        protected abstract T self();

        public T setHarm(int harm)  {
            FastFood.this.harm = harm;
            return self();
        }
    }
}

abstract class Pizza extends FastFood {
    protected List<String> toppings = new ArrayList<>();  //optional
    protected int size;  //obligatory

    protected Pizza(int size)  {this.size = size;}

    public abstract class Builder<T extends Builder<T>> extends FastFood.Builder<T>  {
        public T addTopping(String topping)  {
            toppings.add(topping);
            return self();
        }
    }
}

class CaliforniaPizza extends Pizza {
    private boolean addOlives;

    private CaliforniaPizza(int size) {super(size);}

    public static Builder builder(int size)  {return new CaliforniaPizza(size).new Builder();}

    public class Builder extends Pizza.Builder<Builder>  {
        @Override
        public CaliforniaPizza build()  {
            return CaliforniaPizza.this;
        }

        @Override
        public Builder self()  {return this;}

        public Builder addOlives(boolean addOlives)  {
            CaliforniaPizza.this.addOlives = addOlives;
            return this;
        }
    }
}

class SicilianPizza extends Pizza {
    private boolean addCheese;

    private SicilianPizza(int size)  {super(size);}

    public static Builder builder(int size)  {
        return new SicilianPizza(size).new Builder();
    }

    public class Builder extends Pizza.Builder<Builder>  {
        @Override
        public SicilianPizza build()  {return SicilianPizza.this;}

        @Override
        public Builder self()  {return this;}

        public Builder addCheese(boolean addCheese)  {
            SicilianPizza.this.addCheese = addCheese;
            return this;
        }
    }
}

abstract class Drink extends Stuff {
    protected double density;
    protected double alcoholVolume;

    protected Drink(double density)  {this.density = density;}

    public abstract class Builder<T extends Builder<T>> extends Stuff.Builder<T>  {
        protected abstract Drink build();
        protected abstract T self();

        public T setAlcoholVolume(double alcoholVolume)  {
            Drink.this.alcoholVolume = alcoholVolume;
            return self();
        }
    }
}

abstract class Juice extends Drink {
    private String color;

    protected Juice(double density)  {super(density);}

    public abstract class Builder<T extends Builder<T>> extends Drink.Builder<T>  {
        public Builder<T> setColor(String color)  {
            Juice.this.color = color;
            return self();
        }
    }
}
class AppleJuice extends Juice {
    private String appleColor;

    private AppleJuice(double density)  {super(density);}

    public static Builder builder(double density)  {return new AppleJuice(density).new Builder();}

    public class Builder extends Juice.Builder<Builder>  {
        @Override
        public AppleJuice build()  {
            return AppleJuice.this;
        }

        @Override
        public Builder self()  {
            return this;
        }

        public Builder setAppleColor(String appleColor)  {
            AppleJuice.this.appleColor = appleColor;
            return this;
        }
    }
}

class OrangeJuice extends Juice{
    private int orangeSize;

    private OrangeJuice(double density)  {super(density);}

    public static Builder builder(double density)  {return new OrangeJuice(density).new Builder();}

    public class Builder extends Juice.Builder<Builder>  {
        @Override
        public OrangeJuice build()  {return OrangeJuice.this;}

        @Override
        public Builder self()  {return this;}

        public Builder setOrangeSize(int orangeSize)  {
            OrangeJuice.this.orangeSize = orangeSize;
            return this;
        }
    }
}


推荐答案

您所在的行是:

public FastFood testFood(FastFood.Builder fastFoodBuilder) {

而且:

abstract class FastFood extends Food  {
    ...
    public abstract class Builder<T extends Builder<T>> extends Food.Builder<T> {

应该警告说, FastFood.Builder 是泛型类型。

There should be a warning saying that FastFood.Builder is a generic type.

参数类型必须适当地设为泛型。

The parameter type needs to be made appropriately generic. A wildcard will do (constraints will be inferred).

public FastFood testFood(FastFood.Builder<?> fastFoodBuilder) {

这篇关于Java Builder类的泛型层次结构:如何使build()返回正确的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-26 23:31