Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Java构造函数必须是公共的或受保护的,才能将类扩展到包之外?_Java_Inheritance_Constructor_Default_Access Modifiers - Fatal编程技术网

为什么Java构造函数必须是公共的或受保护的,才能将类扩展到包之外?

为什么Java构造函数必须是公共的或受保护的,才能将类扩展到包之外?,java,inheritance,constructor,default,access-modifiers,Java,Inheritance,Constructor,Default,Access Modifiers,以下是我的ProtectedConstructor.java源代码: package protectCon; public class ProtectedConstructor{ public int nothing; ProtectedConstructor(){ nothing = 0; } } 下面是使用ProtectedCon.java的源代码: package other; import protectcon.ProtectedConstr

以下是我的
ProtectedConstructor.java
源代码:

package protectCon;

public class ProtectedConstructor{
    public int nothing;
    ProtectedConstructor(){
        nothing = 0;
    }
}
下面是使用ProtectedCon.java的
源代码:

package other;

import protectcon.ProtectedConstructor;

public class UsingProtectedCon extends ProtectedConstructor{   //**Line 4**
    public static void main(String... a) {  
    }
}
当我使用protectedcon.java编译
时,我在上面显示的第4行得到错误。它说ProtectedConstructor()不是公共的;因此无法在包外访问

然而,既然我的类是公共的,我就不能在包外扩展它吗。无论如何,我都不会创建它的任何实例

现在,如果我将
ProtectedConstructor
类的构造函数设置为
public
protected
,那么代码编译得很好,没有错误


那么,为什么构造函数必须是
公共的
受保护的
,而不仅仅是具有默认访问权限呢?

在您的类中,ProtectedConstructor是用包私有访问权限定义的 这意味着在包外部,它甚至不被从ProtectedConstructor类扩展而来的类看到

使用“受保护”访问修饰符定义构造函数,您将完成以下操作:

 package protectCon;

public class ProtectedConstructor{
    public int nothing;
    protected ProtectedConstructor(){
        nothing = 0;
    }
}

构造函数
是类的成员,如
字段
方法
,所以访问修饰符应用于它


当您在B中扩展类A时,A的默认构造函数将从B的构造函数隐式调用(如果您不调用任何重载构造函数)

如果要在类的包之外扩展类,它必须有一个
公共的
受保护的构造函数,因为在Java中,每个构造函数都必须从其超类调用构造函数

因此,每个构造函数中都有一个隐含的
super()
调用,而该构造函数的第一个语句不是
this()
,也不是显式调用
super()
。如果您根本不指定构造函数,Java将添加一个默认的无参数构造函数,因此实际上您的代码如下所示:

public class UsingProtectedCon extends ProtectedConstructor {
    public UsingProtectedCon() {
        super();
    }

    public static void main(String... a) {   
    }
}

因此,换句话说,您的代码无法编译,因为无法解析对默认构造函数中的
super()
的调用

您的构造函数不是公共的。默认范围是包私有。

回答了您的问题。子类只访问其父类的受保护成员,如果它涉及其父类的实现。因此,如果父类构造函数受保护且位于不同的包中,则无法在子类中实例化父对象。由于子类的默认构造函数将尝试调用父类构造函数,因此出现此错误


请参阅此项或详细信息

以避免所有混淆,请按此操作。 包装保护

public class ProtectedConstructor{
    public int nothing;
    public ProtectedConstructor(){
        nothing = 0;
    }
}


package other;

import protectCon.ProtectedConstructor;
public class UsingProtectedCon extends ProtectedConstructor{   //**Line 4**

    public UsingProtectedCon(){
      super();
      }


  public static void main(String... a){   
    }
}

您可以拥有公共、受保护(供内部使用)甚至私有的构造函数

一个简单的例子是String,它有
public
构造函数供通用,包本地构造函数供内部使用

ObjectOutputStream类有一个公共构造函数,它接受OutputStream和一个受保护的
构造函数,后者只能由子类使用


顺便说一句:如果你有一个
抽象
类,将构造函数
公开
是否有意义提示:这与受保护的
相同

如果子级将具有父级中私有的构造函数,我们可以使用该构造函数创建子级实例并将其强制转换为父级类型。
因此,为了防止这种情况发生,java编译器不允许构造函数具有父级中私有的构造函数。

挑剔:java中没有重写的构造函数。