【问题标题】:why a class can not be subclassed if i declare its default constructor as private如果我将其默认构造函数声明为私有,为什么一个类不能被子类化
【发布时间】:2014-05-14 18:44:25
【问题描述】:

在一个类中,我可以使用不同的参数类型拥有任意数量的构造函数。我将所有构造函数设为私有,它没有给出任何错误,因为我的隐式默认构造函数是公共的但是当我将隐式默认构造函数声明为私有时,它在扩展类时显示错误。 为什么?

这很好用

public class Demo4  {
    private String name;
    private int age;
    private double sal;

    private Demo4(String name, int age) {
        this.name=name;
        this.age=age;   
    }

    Demo4(String name) {
        this.name=name;
    }

    Demo4() {
        this("unknown", 20);
        this.sal=2000;
    }

    void show(){
        System.out.println("name"+name);
        System.out.println("age: "+age);
    }
}

这个不能继承

public class Demo4  {
    private String name;
    private int age;
    private double sal;

    private Demo4(String name, int age) {
        this.name=name;
        this.age=age;
    }

    Demo4(String name) {
        this.name=name;
    }

    private Demo4() {
        this("unknown", 20);
        this.sal=2000;
    }

    void show() {
        System.out.println("name"+name);
        System.out.println("age: "+age);
    }
}

【问题讨论】:

  • 您希望子类如何调用private 构造函数?
  • difference between access level modifiers 上的这篇文章可能会有所帮助
  • @lgraham076 感谢您的链接
  • @rgettman 我没想到会调用私有构造函数。我看到的是,当我将我的无参数构造函数设为私有时,它显示错误,而它与其他私有构造函数一起运行良好.. 但后来我意识到,根据最近的评论,我的疑问很清楚,即使有一个可以访问的构造函数我可以继承它

标签: java constructor


【解决方案1】:

如果我将一个类的默认构造函数声明为私有,为什么它不能被子类化

子类中的构造函数必须调用超级构造函数(可以是隐式的或显式的),才能完全构造对象。超级构造函数调用链一直到Object 类,Java 中所有类的超类。

如果任何超级构造函数对子类不可见,则无法完全构造 then 对象。

解决此问题的一种方法是在超类protected 中创建构造函数。这样超级构造函数只对子类可见。

【讨论】:

    【解决方案2】:

    如果超类中的任何构造函数都是可访问的,您可以将其子类化,只需在子类的构造函数中使用 super(..) 调用可访问的超级构造函数。

    我可以像这样子类化您的第二个示例:

         super("A string");
    

    【讨论】:

    • 问题是关于子类而不是你如何从子类中调用。
    【解决方案3】:

    一点额外信息,对于默认构造函数,总是隐式调用super()。相反,对于非默认构造函数,应该显式调用(如果父类中没有可访问的构造函数)到可访问的父类的构造函数或同一类的构造函数。例如

    package com.test;
    
    class A {
    
        private A() {
          //implicit call to java.lang.Object.super()
        }
    
        public A(String a) {
          //implicit call to java.lang.Object.super()
        }
    }
    
    public class B extends A {
    
        public B(String a, String b) {
            this(a);
        }
    
        public B(String a) {
            super(a);
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多