Java使用Package Private Constructor继承公共类

时间:2017-02-02 10:21:46

标签: java inheritance visibility

我来自C ++背景,我刚刚使用Java中的Access-Modifiers,我决定玩一些代码,现在我收到一个错误:

  

YouArePublic()在YouArePublic中不公开;无法访问   外包装

我不确定为什么。我知道YouArePublic类中的构造函数是默认的,因此我无法在其自己的包之外的任何其他类中创建它的对象,但我并不是真的在这里创建一个对象。

编译器是否隐式尝试创建Tester类的对象,从而调用其默认的无参数构造函数,然后使用super()调用其超类YouArePublic的构造函数?但是main()是静态的,所以它不需要创建一个类的实例来调用它。

我不确定这里发生了什么,真的需要一些帮助。

package one;

import two.YouArePublic;

class Tester extends YouArePublic { // Inheritance in different package
    public static void main(String args[]) {

        Tester ot = new Tester();
        ot.displayMessage();

    }
}


package two;

public class YouArePublic {
    String message = "You are public in package TWO!";

    YouArePublic() { super(); }


    public void displayMessage() {
        System.out.println(message);
    }    
}

4 个答案:

答案 0 :(得分:2)

问题是类本身不是公共的,因此,正如消息所说,无法从包外部访问。只需公开,你应该没问题(如你所知,将创建一个默认的公共构造函数):

public class Tester extends YouArePublic {

答案 1 :(得分:0)

就像您解释的那样,构造函数需要为public,否则您无法调用它,并且无法实例化类Tester

答案 2 :(得分:0)

你的main方法可能是静态的,但这只意味着可以在不首先实例化对象的情况下调用它。在main方法中,您将创建一个对象:

Tester ot = new Tester();

如果您没有自己明确定义构造函数,那么编译器会生成一个带super()调用的隐式默认构造函数。它看起来像这样:

public Tester() {
    super();
}

这意味着它会尝试调用具有默认可见性的构造函数YouArePublic() { super(); },即包私有。由于YouArePublic位于另一个包中,因此无法从Tester访问它。

答案 3 :(得分:0)

您只能对静态方法进行静态调用。因为不需要初始化。但是这里你没有进行静态调用,你的父类方法也不是静态的。为此,您应该修改您的父类,如下所示。(但仅此一点就不足以编译该类)

package one;

import two.YouArePublic;

class Tester extends YouArePublic { // Inheritance in different package
    public static void main(String args[]) {    
        Tester.displayMessage();   //No object created 
    }
}   

package two;

public class YouArePublic {
    String message = "You are public in package TWO!";

    YouArePublic() { super(); }    

    public void static displayMessage() { //static modifier added
        System.out.println(message);
    }    
}

例外原因: 创建子类的对象时,首先调用父类的构造函数,然后调用子类的构造函数。对于编译器,您的代码与下面显示的代码相同。

class Tester extends YouArePublic { 
    public Tester(){
        super();
    }

    public static void main(String args[]) {
        Tester ot = new Tester();
        ot.displayMessage();    
    }
}

在您的情况下,无法完成对超级构造函数的调用,因为父构造函数的可见性为' default'并且只对同一个包中的类可见。

如果您没有向父类添加任何构造函数,则编译器假定它具有公共默认构造函数。您通过创建自己的构造函数来限制它。