Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java AbstractFactory中声明静态方法的缺点_Java_Design Patterns_Factory Pattern - Fatal编程技术网

Java AbstractFactory中声明静态方法的缺点

Java AbstractFactory中声明静态方法的缺点,java,design-patterns,factory-pattern,Java,Design Patterns,Factory Pattern,根据Head-First设计模式,在工厂类中声明静态方法的缺点是——“您不能子类化和更改getPizza方法的行为”。工厂类使用getPizza方法来决定返回哪种类型的对象。如果我理解正确,我的班级是 public class PizzaFactory { public static Pizza getPizza(String type) { if (type.equals("cheese")) return new

根据Head-First设计模式,在工厂类中声明静态方法的缺点是——“您不能子类化和更改getPizza方法的行为”。工厂类使用getPizza方法来决定返回哪种类型的对象。如果我理解正确,我的班级是

    public class PizzaFactory {
        public static Pizza getPizza(String type) {
            if (type.equals("cheese"))
                return new CheesePizza();
            else if (type.equalsIgnoreCase("thisCrust"))
                return new ThinCrustPizza();
            return null;
        }
    }
即使这个方法是静态的,我也可以创建一个子类,比如-

public class DelhiPizzaFactory extends PizzaFactory {
    public static Pizza getPizza(String type) {
        if (type.equals("cheese"))
            return new CheesePizza();
        else if (type.equalsIgnoreCase("thisCrust"))
            return new ThinCrustPizza();
        return null;
    }
}
我可以交替使用超类和子类

public class PizzaStore {

    Pizza pizza;

    public void orderPizza(String type) {
        pizza = DelhiPizzaFactory.getPizza(type);
        pizza.prepare();
        pizza.bake();
    }
}

那么缺点是什么呢?

既然要防止重写,就需要将方法设置为final,例如:

公共类比萨饼工厂{
公共静态最终Pizza getPizza(字符串类型){
[...]
}


通过这种方式,您可以防止重写,如果这是您在本例中想要的,尽管在其他情况下,是的,通过不使其成为
final
来允许重写也会很有用。

因为您想要防止重写,所以您需要使您的方法成为
final
,例如:

公共类比萨饼工厂{
公共静态最终Pizza getPizza(字符串类型){
[...]
}


通过这种方式,您可以防止覆盖,如果这是您在本例中想要的,尽管在其他情况下,是的,通过不使其成为
final
来允许覆盖也很有用。

这是一个用例问题。 考虑情况,您使用的API有以下几种全局API的方法。
public void setPizzaFactory(PizzaFactory factory) {
    this.pizzaFactory=factory;
   // set pizza factory and 
}
通常,您可以将两个工厂作为参数传递给该方法,但如果我们的API将使用您刚才设置的PizzaFactory,并调用其
getPizza()
方法,它将始终使用
getPizza()
方法在
PizzaClass
中声明,尽管您可能已将其他派生类作为工厂对象传递

如果您的工厂中有非静态方法,那么您可以这样做

api.setPizzaFactory(新的DoubleCheesePizzaFactory)
where
DoubleCheesePizzaFactory
覆盖
getPizza
方法,始终在每个比萨饼中添加额外的奶酪。这样,内部“烘焙”api将使用来自DoubleCheesePizzaFactory的
getCheese
方法版本,而不是
PizzaFactory.getPizza
版本(又名
super.getPizza


因此,缺点就是这样:您不能(通过重写)更改
super
类中方法的行为。

这是一个用例问题。 考虑情况,您使用的API有以下几种全局API的方法。
public void setPizzaFactory(PizzaFactory factory) {
    this.pizzaFactory=factory;
   // set pizza factory and 
}
通常,您可以将两个工厂作为参数传递给该方法,但如果我们的API将使用您刚才设置的PizzaFactory,并调用其
getPizza()
方法,它将始终使用
getPizza()
方法在
PizzaClass
中声明,尽管您可能已将其他派生类作为工厂对象传递

如果您的工厂中有非静态方法,那么您可以这样做

api.setPizzaFactory(新的DoubleCheesePizzaFactory)
where
DoubleCheesePizzaFactory
覆盖
getPizza
方法,始终在每个比萨饼中添加额外的奶酪。这样,内部“烘焙”api将使用来自DoubleCheesePizzaFactory的
getCheese
方法版本,而不是
PizzaFactory.getPizza
版本(又名
super.getPizza


因此,不利因素就是这样:您无法改变行为(通过重写)
super
类中的方法。

停止重写也必须是
final
停止重写也必须是
final
停止重写我在eclipse中尝试了这一点,这正是您所说的!如果我不想重写getPizza方法,那么我应该声明它为final。如果我只使用静态,子类将不知道ir新的实现是否会被采用。现在有意义了。谢谢!很高兴我能提供帮助。因此,一般来说,没有必要将方法声明为static final,因为不需要这样做-它们不会像非static方法一样被重写。仅供参考-使用“重写”时您将观察到的相同行为私有字段。我在eclipse中尝试过这一点,这正是您所说的!如果我不想覆盖getPizza方法,那么我应该将其声明为final。如果我只使用static,子类将不知道它们的新实现是否会被接受。这现在是有意义的。谢谢!很高兴我能提供帮助。所以总体而言,decla没有什么意义re方法静态最终,因为没有这种需要-它们不会像非静态方法一样被重写。仅供参考-使用“重写”私有字段时您将观察到的相同行为。