Java 静态工厂相对于构造函数的缺点
我正在学习有效的Java。第一项为构造函数上的静态工厂方法提供了令人信服的理由 我没有得到第一个缺点,那就是 只提供静态工厂方法的主要缺点是 没有公共或受保护构造函数的类不能被子类化 既然静态方法不能被继承,为什么我需要对具有静态工厂方法的类进行子类化Java 静态工厂相对于构造函数的缺点,java,constructor,static-factory,Java,Constructor,Static Factory,我正在学习有效的Java。第一项为构造函数上的静态工厂方法提供了令人信服的理由 我没有得到第一个缺点,那就是 只提供静态工厂方法的主要缺点是 没有公共或受保护构造函数的类不能被子类化 既然静态方法不能被继承,为什么我需要对具有静态工厂方法的类进行子类化 有人能解释一下吗。对于要创建的子类实例,必须调用其构造函数 构造函数必须做的第一件事是调用其父类构造函数之一(如果不明确添加它,编译器会为您插入对super()的调用) 如果所有的父类构造函数都是私有的,那么子类就不能调用它们中的任何一个,这使得
有人能解释一下吗。对于要创建的子类实例,必须调用其构造函数 构造函数必须做的第一件事是调用其父类构造函数之一(如果不明确添加它,编译器会为您插入对
super()
的调用)
如果所有的父类构造函数都是私有的,那么子类就不能调用它们中的任何一个,这使得父类实际上是最终的,也就是说,不可能子类化。当你实例化
一个基类时,发生的第一件事就是调用它的父类的构造函数。如果父类构造函数
是私有的,则不能从类主体外部调用它,因此将无法工作。请记住,当您阅读有关继承的内容时,有一点指出,如果您想使用super()
,它应该是基类构造函数中的第一行,如果您没有在基类中显式使用super()
,编译器会自动将它放在那里。想想如果您的父类构造函数是private
,调用super()
- 在子类中,每个构造函数必须在调用超类构造函数的构造函数开始时调用
super(..)
(。
可能是参数)李>
- 要实现正确的静态工厂模式,具有此模式的类的所有构造函数必须是
私有的
,以防止在不使用工厂方法的情况下实例化类
因此,由于带有工厂方法的基类的构造函数必须是私有的,派生类将无法调用super(..)
,这将不允许编译子类。这意味着您的类将不支持某些继承特性,例如您不能重写它的任何方法,不能将其用作动态分派的超级类型 假设您有一个名为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() { }
}
一切都很好。但是现在您还需要一个名为程序员的类,您突然意识到程序员也是人
但是突然之间,你不能
class Programmer extends Person { }
因为Person
没有任何public
构造函数。什么部分“…没有public或protected构造函数的类不能被子类化。”不清楚?问题更新了..我没有得到静态工厂方法和“没有公共或受保护构造函数的类不能被子类化”之间的关系.我不知道为什么人们这么快就否决了一个问题..让我们来解释这个问题first@Jarrord-现在你能解释一下吗?我只是不明白(上面的解释)与静态工厂方法相关?只提供静态工厂方法的主要缺点是没有公共或受保护构造函数的类不能被子类化。
这是什么意思?这意味着,如果您只提供静态方法
作为类的实例化源,而所有构造函数都是私有的
,则由于@JB Nizet和my中解释的原因,您不能对该类进行子类化answer@Prateek-但是,既然静态方法不能被调用,为什么我需要对具有静态工厂方法的类进行子类化呢inherited@Anand这正是该声明试图表达的观点。如果你打算扩展你的类,你不应该只有静态工厂方法
和所有构造函数私有
当然受保护的
构造函数是有用的。拥有公共构造函数有什么独特的用处?可以说,不能对静态工厂进行子类化实际上是一件好事。正如《有效Java》中所指出的:“可以说,这是一种因祸得福,因为它鼓励程序员使用组合而不是继承”。在这种情况下,您仍然可以定义一个类程序员,该类程序员遵从Person来创建对象。