【问题标题】: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,最终目的是记录类信息而不仅仅是类的实例。

但是,这不是我想讨论的,我想听听您对超类的受保护构造函数的看法,拥有它的好处和坏处,而不仅仅是针对这种特殊情况但对于您可以想象的其他情况或场景。

问候,

【问题讨论】:

    标签: java constructor protected


    【解决方案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
    猜你喜欢
    • 2020-03-06
    • 2016-12-19
    • 2013-07-17
    • 2012-12-24
    • 1970-01-01
    • 2011-01-13
    • 2011-05-30
    • 1970-01-01
    • 2023-03-21
    相关资源
    最近更新 更多