【问题标题】:extends of the class with private constructor使用私有构造函数扩展类
【发布时间】:2010-10-17 10:21:33
【问题描述】:

假设我们有以下代码:

class Test {
    private Test() {
        System.out.println("test");
    }

}

public class One extends Test {

    One() {
        System.out.println("One");
    }

    public static void main(String args[]) {

        new One();
    }
}

当我们创建一个对象One时,它最初被称为父类构造函数Test()。但由于Test() 是私有的 - 我们得到一个错误。 一个很好的例子和摆脱这种情况的方法是多少?

【问题讨论】:

    标签: java constructor


    【解决方案1】:

    没有出路。您必须创建一个可用的(protectedpublic 或默认)超级构造函数才能扩展 test

    这种表示法通常用于实用程序类或单例中,您不希望用户通过扩展它并实例化子类或简单地调用您的构造函数来创建自己的类的实例类。

    当您有一个只有private 构造函数的class 时,您还可以将class 更改为final,因为它根本无法扩展。


    另一种解决方案是在test 中创建一个方法,该方法创建test 的实例,并将每个方法调用从One 委托给test 实例。这样您就不必扩展test

    class Test {
        private Test() {
            System.out.println("test");
        }
        public static Test getInstance(){
            return new Test();
        }
        public void methodA(){
            //Some kind of implementation
        }
    }
    
    public class One {
        private final Test test;
        One() {
            System.out.println("One");
            test = Test.getInstance();
        }
    
        public void methodA(){
            test.methodA();
        }
    
        public static void main(String args[]) {
            new One();
        }
    }
    

    【讨论】:

    • Test 类的方法getInstance() 应该是静态的。否则无法拨打Test.getInstance()之类的电话。
    【解决方案2】:

    使test 的构造函数非private 或将One 移动到test

    顺便说一句,您的示例代码包含一些问题:

    • 类应命名为标题大小写(Test 而不是test
    • 我建议将One 的构造函数设为private,除非它是从同一个包中的不同类调用的

    【讨论】:

      【解决方案3】:

      其实,我找到了一条出路。像这样:

      class Base {
          private Base() {
      
          }
      
          public void fn() {
              System.out.println("Base");
          }
      
          public static class Child extends Base {
              public void fn() {
                  System.out.println("Child");
              }
          }
      
          public static Base getChild() {
              return new Child();
          }
      }
      

      现在,您可以使用 getChild() 来获取扩展类的实例。

      【讨论】:

      • 这仅在放置静态内部类时有效,因为内部类可以访问私有方法。不幸的是,这无济于事,因为如果您能够更改类,那么首先将构造函数设置为受保护或公开会更好。..
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-29
      • 2016-10-22
      • 2013-11-15
      相关资源
      最近更新 更多