创建类的受保护构造函数有啥好处和坏处
Posted
技术标签:
【中文标题】创建类的受保护构造函数有啥好处和坏处【英文标题】:What are the benefits and the disadvantages of creating a protected constructor of a Class创建类的受保护构造函数有什么好处和坏处 【发布时间】:2012-01-27 00:07:23 【问题描述】:我有一个愚蠢的疑问,但我想听听一些关于它的意见。
我有一个超类(MySuperClass),然后,我有大约 70 个类继承自这个超类(Bean 类)。
这个超类的目的是使用反射来实现“toString”方法,通过这种方式,我可以确保所有这 70 个类都有 toString 方法。这70个类都是bean,最终目的是记录类信息而不仅仅是类的实例。
但是,这不是我想讨论的,我想听听您对超类的受保护构造函数的看法,拥有它的好处和坏处,而不仅仅是针对这种特殊情况但对于您可以想象的其他情况或场景。
问候,
铁
【问题讨论】:
【参考方案1】:如果您的目标是确保MySuperClass
永远不会直接通过new MySuperClass()
实例化,只有它的子类是,那么声明类abstract
更有意义;见http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html。这就是抽象类的全部意义所在。那么构造函数可以是public
或者protected
,这并不重要。
在 非-abstract
类中包含所有构造函数 protected
的原因是如果您确实打算使用 new MySuperClass()
实例化该类本身,但只希望它被 子类和其包的其他成员(例如“工厂”对象)实例化。不过,这听起来不像您想要做的。
【讨论】:
好吧,将构造函数声明为受保护的目的是禁止我的超类的公共实例化。但我想听听对此的一些意见。 @FernandoMoyano:是的,但是为什么你要禁止你的超类的公共实例化?听起来您真正想要 - 或真正应该想要 - 根本不允许您的超类的任何直接实例化。也就是说,除了作为一个超类之外,这个类听起来毫无用处,而且没有理由让这个超类的实例不是其子类之一的实例。 谢谢@ruakh,我想你已经准确地描述了我想要做的事情:“......根本不允许你的超类的任何直接实例化。也就是说,听起来这个类是无用的除了作为超类,没有理由让这个超类的实例不是其子类之一的实例......" @FernandoMoyano:那么,这意味着你想要一个抽象类。请参阅我的答案中的链接。 :-)【参考方案2】:如果您只想使用返回此类型实例的静态方法创建一个实例,则可以使构造函数受保护。当对象很重并且创建许多实例会影响内存时,有利于内存分配
public class A
private static A instance = null;
protected A()
// Exists only to defeat instantiation.
public static A getInstance()
if(instance == null)
instance = new A();
return instance;
【讨论】:
同一个包中的B类可以说A a = new A();
。再见,你的单身。
嗨@HusseinX,感谢您的回答。我不是在寻找单身人士,@ruakh 已经正确地描述了我想要做的事情。【参考方案3】:
受保护的构造函数有一个抽象类不具备的有用特性:同一个包中的类、子类和类本身的静态方法可以创建该类的实例,而外部人员则不能。抽象类根本无法实例化,无论构造函数的可访问性如何。
话虽如此,我更希望类是抽象的。受保护的构造函数不能阻止子类或同一包中的任何类说出BaseClass x = new BaseClass();
。一个受保护的构造函数对我说“代码可能在某个地方实例化了这个类”,并给了我另一件事需要跟踪。
【讨论】:
嗨@cHao,感谢我们的回答。这不能是一个抽象类,因为它使用反射实现了 to string 方法。 抽象类中的反射有一些限制吗?对我来说新闻...抽象类应该具有与非抽象类相同的功能,当然不包括实例化的能力。 哎呀,你说得对,我刚刚测试过,效果很好。我确信这是不可能的。谢谢@cHao以上是关于创建类的受保护构造函数有啥好处和坏处的主要内容,如果未能解决你的问题,请参考以下文章
请问把基类构造函数声明为protected有啥好处呢(抽象基类)