类的扩展与私有构造函数

62

假设我们有以下代码:

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()是私有的,我们会收到错误提示。

这是一个很好的例子,同时也是一种解决这种情况的方法?

3个回答

64
没有办法,你必须创建一个可用的(protectedpublic 或默认的)超类构造函数才能扩展 test
通常在实用程序类或单例中使用这种符号,这样你就不希望用户通过扩展和实例化子类或仅调用类构造函数而创建类的实例。
当你有一个只有私有构造函数的 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();
    }
}

5
Test 类的 getInstance() 方法应该是静态的,否则就无法像这样调用:Test.getInstance() - vanje

1

test的构造函数设为非private,或将One移入test中。

顺便提一下,你的示例代码存在几个问题:

  • 类应该以大写字母开头(Test而不是test
  • 我建议将One的构造函数设为private,除非它在同一包中的另一个类中被调用。

-1

其实,我发现有一种方法。就像这样:

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()方法获取扩展类的实例。

15
只有在使用静态内部类时才能这样做,因为私有方法可以被内部类访问。不幸的是,这并没有什么帮助,因为如果你能够更改类,最好的方法是一开始就将构造函数设置为受保护或公共的。 - Lodewijk Bogaards

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接