如果我们不在子类中创建子类对象,为什么父类必须有一个默认的构造函数?

时间:2016-08-12 10:34:17

标签: java

class handleException extends Exception
{
    public handleException(String s)
    {
        super(s);
    }
}

public class unhandled extends handleException {
    public static void main(String args[])throws handleException
    {
        float a=7/0;
        if(Double.isNaN(a))
        {
            throw new handleException("Exception is handled");
        }
    }


}

这段代码给出了编译错误,说handleException是父类没有任何默认构造函数,但是为什么没有调用子类构造函数unhandled(),所以不会调用super()所以为什么是它给编译时错误。

3 个答案:

答案 0 :(得分:5)

因为您还没有为unhandled指定任何构造函数,编译器为您提供了default one,在这种情况下如下所示:

public unhandled() { // It's public because `unhandled` is public
    super();
}

默认构造函数没有参数,期望其超类具有无参数构造函数,并且具有与类相同的可访问性。无论您的代码是否调用该构造函数,编译器都会插入此函数;它不是"有时是,有时没有"事情。 :-)由于超类unhandledException没有没有参数的构造函数,编译器无法编译插入的默认构造函数。

如果您希望unhandled仅使用参数构造,则需要为构造函数提供参数。

或者,如果您希望永远不构造unhandled,则需要提供一个私有的构造函数(可能没有参数):private unhandled() { super(null); }

您可能想知道为什么默认构造函数始终没有参数,并且期望超类构造函数没有参数。答案是:因为它是如何设计的。 :-) 可以设计得更复杂。例如,他们可以将默认构造函数基于超类中的可用构造函数,但在编写编译器方面更复杂,而在理解工作原理方面则更复杂。相反,它保持简单,如果你想要一个不同的构造函数,你只需提供一个。

答案 1 :(得分:1)

您的类unhandled没有任何构造函数,Java将为您创建一个没有参数的默认构造函数。该默认构造函数想要调用super(),这就是它在handleException中寻找无效构造函数的原因。另请参阅Java语言规范https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.8.9

答案 2 :(得分:1)

目前基本上你只处理一种类型的构造函数,即Parameterized Constructor,但实际上有两种类型的构造函数。

  1. 默认构造函数
  2. 参数化构造函数
  3. Types of constructors in java

    这里要注意的要点是:

      

    规则:如果类中没有构造函数,编译器会自动创建默认构造函数。

    现在您没有任何构造函数定义您的班级unhandled。所以编译器会自动创建一个这样的构造函数:

    public class unhandled extends handleException {
    
        //added by compiler
        public unhandled() { 
            super(); //note that this super will call the non-parameterized constructor of your parent class, i.e., handleException
        }
    
        public static void main(String args[])throws handleException
        {
            float a=7/0;
            if(Double.isNaN(a))
            {
                throw new handleException("Exception is handled");
            }
        }
    }
    

    现在单词super()没有任何参数,所以它调用了父类的默认OR非参数化构造函数,因为你的父类handleException没有#&# 39; t,所以编译器说:

    Sorry, but `handleException` don't have a default constructor, I can't invoke that.