简体   繁体   English

Java用Package Private Constructor继承公共类

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

I come from a C++ background, I was just going through Access-Modifiers in Java and I decided to play around with some code and now I am getting an error: 我来自C ++背景,我刚刚经历过Java中的Access-Modifiers,所以我决定尝试一些代码,现在遇到错误:

YouArePublic() is not public in YouArePublic; YouArePublic()在YouArePublic中不公开; cannot be accessed from outside package 无法从外部包访问

I am not sure why. 我不知道为什么。 I know that the Constructor in class YouArePublic is default and hence I can't create an object of it in any other class outside its own package but I am not really creating an object here. 我知道类YouArePublic中的Constructor是默认的,因此我无法在其自己的包之外的任何其他类中创建它的对象,但是我并不是在这里真正创建对象。

Does the compiler implicitly tries to create an object of Tester class thus calling its default parameter-less constructor which is then invoking the constructor of its superclass YouArePublic using super()? 编译器是否隐式尝试创建Tester类的对象,从而调用其默认的无参数构造函数,然后使用super()调用其超类YouArePublic的构造函数? but then main() is static so it doesn't need to create an instance of the class to invoke it. 但是main()是静态的,因此不需要创建该类的实例来调用它。

I am not sure what is happening here, Really need some help. 我不确定这里发生了什么,真的需要一些帮助。

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

The problem is the class itself isn't public, and thus, as the message says, cannot be accessed from outside the package. 问题是该类本身不是公共的,因此,如消息所述,不能从包外部访问该类。 Just make it public, and you should be OK (as you noted, a default public constructor would be created): 只需将其公开,就可以了(如前所述,将创建一个默认的公共构造函数):

public class Tester extends YouArePublic {

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

Your main-method might be static, but that only means that it can be called without instantiating an object first. 您的主方法可能是静态的,但这仅意味着可以在不首先实例化对象的情况下调用它。 In your main-method you are creating an object: 在您的主要方法中,您正在创建一个对象:

Tester ot = new Tester();

You are right that the compiler generates an implicit default constructor with super() call, if you don't explicitly define a constructor yourself. 如果您自己没有显式定义构造函数,那么编译器通过super()调用生成隐式默认构造函数是正确的。 It looks like this: 看起来像这样:

public Tester() {
    super();
}

This means that it tries to call your constructor YouArePublic() { super(); } 这意味着它将尝试调用构造函数YouArePublic() { super(); } YouArePublic() { super(); } which has default visibility, aka package private. YouArePublic() { super(); } (具有默认可见性,也称为私有包)。 Since YouArePublic is in another package, it can't be accessed from Tester . 由于YouArePublic位于另一个软件包中,因此无法从Tester进行访问。

You can do static invocations of static methods only. 您只能对静态方法进行静态调用。 For that initialization is not required. 为此,不需要初始化。 But here you are not doing a static invocation and your parent class methods are not static. 但是这里您不是在进行静态调用,并且您的父类方法也不是静态的。 For this you should modify your parent class as below.(But this alone wont be enough to compile the class) 为此,您应该按以下方式修改父类(但是仅此一项不足以编译该类)

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

Reason for exception : When the object of the child class is created the constructor of the parent class is invoked first and then the constructor of the child class.For the compiler your code is same as code shown below. 发生异常的原因:创建子类的对象时,将先调用父类的构造函数,然后再调用子类的构造函数。对于编译器,您的代码与以下代码相同。

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

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

In your case the call to super constructor cannot be completed as the visibility of parent constructor is 'default' and is visible to classes in the same package only. 在您的情况下,对超级构造函数的调用无法完成,因为父构造函数的可见性为“默认”,并且仅对同一包中的类可见。

If you do not add any constructor to your parent class compiler assumes it has a public default constructor. 如果您不向父类编译器添加任何构造函数,则假定它具有公共默认构造函数。 Your are restricting this by creating your own constructor. 您正在通过创建自己的构造函数来限制这一点。

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

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