繁体   English   中英

Java用Package Private Constructor继承公共类

[英]Java Inheriting a public class with Package Private Constructor

我来自C ++背景,我刚刚经历过Java中的Access-Modifiers,所以我决定尝试一些代码,现在遇到错误:

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

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

编译器是否隐式尝试创建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);
    }    
}

问题是该类本身不是公共的,因此,如消息所述,不能从包外部访问该类。 只需将其公开,就可以了(如前所述,将创建一个默认的公共构造函数):

public class Tester extends YouArePublic {

就像您解释的那样,构造函数必须是public否则您将无法调用它并且无法实例化Tester类。

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

Tester ot = new Tester();

如果您自己没有显式定义构造函数,那么编译器通过super()调用生成隐式默认构造函数是正确的。 看起来像这样:

public Tester() {
    super();
}

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

您只能对静态方法进行静态调用。 为此,不需要初始化。 但是这里您不是在进行静态调用,并且您的父类方法也不是静态的。 为此,您应该按以下方式修改父类(但是仅此一项不足以编译该类)

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();    
    }
}

在您的情况下,对超级构造函数的调用无法完成,因为父构造函数的可见性为“默认”,并且仅对同一包中的类可见。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM