静态工厂缺点比构造函数

时间:2013-11-01 19:13:50

标签: java constructor static-factory

我正在阅读Effective Java。第一个项目为构造函数提供了静态工厂方法的令人信服的理由。

我没有得到第一个缺点

  

仅提供静态工厂方法的主要缺点是   没有公共或受保护构造函数的类不能被子类化。

为什么我需要使用静态工厂方法对类进行子类化,因为静态方法不能被继承?

有人可以解释一下。

5 个答案:

答案 0 :(得分:5)

假设您有一个名为Person的课程:

class Person {
  public static Person createWithFirstName(String firstName) {
    return new Person(firstName, null, null);
  }
  // etc. - more factory methods

  // private constructor
  private Person(String firstName, String lastName, String nickname) { }

  // useful method
  public String getDisplayName() { }
}

一切都很好,花花公子。但是现在你还需要一个名为Programmer的类,你突然意识到程序员也是人!

但突然之间,你不能只是

class Programmer extends Person { }

因为Person没有任何public构造函数。

答案 1 :(得分:2)

对于要创建的子类的实例,必须调用其构造函数。

构造函数必须做的第一件事就是调用它的一个父类构造函数(如果你没有明确地添加它,编译器会为你插入对super()的调用) 。

如果所有父类构造函数都是私有的,则子类不能调用它们中的任何一个,使父类有效地成为最终类,即不可能进行子类化。

答案 2 :(得分:1)

很少有事实

  • 在子类中,每个构造函数必须在调用超类构造函数的构造函数的开头调用super(..)..可能是参数)。
  • 要实现正确的静态工厂模式,具有此模式的类的所有构造函数必须为private,以防止在不使用工厂方法的情况下实例化类。

因此,由于具有工厂方法的基类的构造函数必须是私有的,派生类将无法调用super(..),这将不允许子类进行编译。

答案 3 :(得分:0)

当您instantiate base类时,首先发生的是调用其parent类的构造函数。如果parent class constructor是私有的,则无法从类体外调用它,因此无效。请记住,当您阅读inheritance时,有一点说明如果您想使用super(),它应该是基类构造函数中的第一行,如果您没有明确使用super()在基类编译器中自动将它放在那里。想想如果parent class constructorprivatesuper()来电失败,会发生什么。

答案 4 :(得分:0)

这意味着您的类不支持某些继承功能,例如,您不能覆盖它的任何方法,您不能将其用作动态分派的超类型。