继承中构造函数的默认访问修饰符

Posted

技术标签:

【中文标题】继承中构造函数的默认访问修饰符【英文标题】:Default access modifier of constructor in Inheritance 【发布时间】:2017-01-12 10:20:00 【问题描述】:

我在网上搜索了一下,才知道默认构造函数的访问修饰符和类的访问级别是一样的,但是看看。

这是一个类

package package2;
public class TestClass1 
    TestClass1()
    
        System.out.println("In parent's contructor");
    

这是另一个继承自前一个的

package package2;

public class TestClass2 extends TestClass1 

      TestClass2()
     
         System.out.println("In TestClass2's contructor");
     


但是当我尝试创建TestClass2的对象时

import package2.*;

class MainClass 


    public static void main(String[] args) 
    
        TestClass2 t2 = new TestClass2(); //Says the constructor TestClass2() is not visible.

    
 

我不明白,TestClass1TestClass2 两个类都具有公共访问权限,因此它们的构造函数也必须是隐式公共的。我在这里缺少哪个概念? o.O

【问题讨论】:

你从哪里读到构造函数的默认访问说明符与它的类的访问说明符相同? Default constructor != Default access specifier of constructor。 JLS 讨论了隐式构造函数(如果你没有在你的类中定义任何构造函数,它会自动创建)。 @Salim - 你也想为答案投票! 【参考方案1】:

我做了一点网络搜索,然后才知道默认构造函数的 访问说明符与类的访问级别相同

默认构造函数与您声明的构造函数之间存在差异。默认构造函数是您未在类中声明的构造函数。

代码中的当前构造函数不是默认构造函数。而且,它具有 default(package-private --- no explicit modifier) 访问权限,因为您已从中省略了任何访问修饰符。

我在这里遗漏了哪个概念?

因此,由于默认访问权限的限制,您在其他包中的类无法找到它。

【讨论】:

default 是 switch 语句中的关键字,不是访问修饰符,Java 中没有访问说明符之类的东西。 @EJP - 抱歉,访问说明符和访问修饰符之间的混淆让我失望了!感谢您的编辑。而且,默认情况下,我指的是包私有。【参考方案2】:

哦,它们是公开的,但仅限于包(我们称之为默认访问修饰符)!

访问修饰符在构造函数、方法和字段之间没有区别。

像这样将 MainClass 移动到同一个包中:

package package2; // <-- !
import package2.*;

class MainClass 


    public static void main(String[] args) 
    
        TestClass2 t2 = new TestClass2(); //OK!
    

或者让构造函数真正公开

public TestClass2()
...

【讨论】:

【参考方案3】:

隐式构造函数是不写任何构造函数时的构造函数。在您的代码中,您已明确编写了构造函数,因此它们不是隐式的。 隐式构造函数由 Java 内部提供,不可见。例如:

package package2;
public class TestClass1 

在上面的类中我们没有写任何构造函数。

package main;
class MainClass 
        public static void main(String[] args) 
        
            TestClass1 t2 = new TestClass1(); //Although we have not written any constructor for TestClass1, but we are able to create object for it. This object creation is done by calling TestClass1's costructor, which is an implicit, invisible constructor provided by java when we explicitly do not write any constructor. 
        

上面,虽然我们没有为TestClass1写任何构造函数,但是我们可以为它创建对象。这个对象的创建是通过调用TestClass1的costructor来完成的,它是java在我们明确不写任何构造函数时提供的一个隐式的、不可见的构造函数。

在您的示例中,您已经明确编写了构造函数并将其设为默认值(默认意味着不公开或私有),这意味着它只能在同一个包中访问。如果您尝试从包外的任何类调用此构造函数,您将收到构造函数不可见的错误,如您的情况:

import package2.*;

    class MainClass 
        public static void main(String[] args) 
        
            TestClass2 t2 = new TestClass2(); //Says the constructor TestClass2() is not visible.
        
     

【讨论】:

以上是关于继承中构造函数的默认访问修饰符的主要内容,如果未能解决你的问题,请参考以下文章

Java 构造函数的默认访问修饰符

在类的构造函数上使用受保护的访问修饰符

Java内构造函数关键字权限修饰符访问控制及面向对象的特性!

JAVA中的四种作用域访问修饰符以及各自的关键字个特点是?

C#中的默认访问修饰符

权限修饰符