简体   繁体   中英

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:

YouArePublic() is not public in 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.

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()? but then main() is static so it doesn't need to create an instance of the class to invoke it.

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. It looks like this:

public Tester() {
    super();
}

This means that it tries to call your constructor YouArePublic() { super(); } YouArePublic() { super(); } which has default visibility, aka package private. Since YouArePublic is in another package, it can't be accessed from 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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