Java 使用包私有构造函数继承 public class
Java Inheriting a public class with Package Private Constructor
我有 C++ 背景,我刚刚经历了 Java 中的访问修饰符,我决定尝试一些代码,但现在我收到一个错误:
YouArePublic() is not public in YouArePublic; cannot be accessed from
outside package
我不知道为什么。我知道 class YouArePublic 中的构造函数是默认的,因此我无法在它自己的包之外的任何其他 class 中创建它的对象,但我并不是真的在这里创建对象。
编译器是否隐式尝试创建 Tester class 的对象,从而调用其默认的无参数构造函数,该构造函数随后使用 super() 调用其 superclass YouArePublic 的构造函数?但是 main() 是静态的,所以它不需要创建 class 的实例来调用它。
我不确定这里发生了什么,真的需要一些帮助。
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);
}
}
问题是 class 本身不是 public,因此,正如消息所说,无法从包外部访问。只需将其设置为 public,你应该没问题(如你所述,将创建一个默认的 public 构造函数):
public class Tester extends YouArePublic {
就像你解释的那样,构造函数必须是 public
否则你无法调用它并且 class Tester
无法实例化。
您的 main-method 可能是静态的,但这仅意味着无需先实例化对象即可调用它。在您的 main-method 中,您正在创建一个对象:
Tester ot = new Tester();
你是对的,如果你自己没有显式定义构造函数,编译器会通过 super()
调用生成一个隐式默认构造函数。它看起来像这样:
public Tester() {
super();
}
这意味着它会尝试调用您的构造函数 YouArePublic() { super(); }
,它具有默认可见性,也就是包私有。由于 YouArePublic
在另一个包中,因此无法从 Tester
.
访问它
您只能对静态方法进行静态调用。对于那个初始化是不需要的。但是在这里您没有进行静态调用,并且您的父 class 方法不是静态的。为此,您应该如下修改您的父级 class。(但仅此一项不足以编译 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);
}
}
异常原因:
当创建子 class 的对象时,首先调用父 class 的构造函数,然后调用子 class.For 的构造函数编译器,您的代码与下面显示的代码相同。
class Tester extends YouArePublic {
public Tester(){
super();
}
public static void main(String args[]) {
Tester ot = new Tester();
ot.displayMessage();
}
}
在您的情况下,无法完成对超级构造函数的调用,因为父构造函数的可见性为 'default',并且仅对同一包中的 classes 可见。
如果您不向父级添加任何构造函数 class 编译器会假定它具有 public 默认构造函数。您通过创建自己的构造函数来限制这一点。
我有 C++ 背景,我刚刚经历了 Java 中的访问修饰符,我决定尝试一些代码,但现在我收到一个错误:
YouArePublic() is not public in YouArePublic; cannot be accessed from outside package
我不知道为什么。我知道 class YouArePublic 中的构造函数是默认的,因此我无法在它自己的包之外的任何其他 class 中创建它的对象,但我并不是真的在这里创建对象。
编译器是否隐式尝试创建 Tester class 的对象,从而调用其默认的无参数构造函数,该构造函数随后使用 super() 调用其 superclass YouArePublic 的构造函数?但是 main() 是静态的,所以它不需要创建 class 的实例来调用它。
我不确定这里发生了什么,真的需要一些帮助。
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);
}
}
问题是 class 本身不是 public,因此,正如消息所说,无法从包外部访问。只需将其设置为 public,你应该没问题(如你所述,将创建一个默认的 public 构造函数):
public class Tester extends YouArePublic {
就像你解释的那样,构造函数必须是 public
否则你无法调用它并且 class Tester
无法实例化。
您的 main-method 可能是静态的,但这仅意味着无需先实例化对象即可调用它。在您的 main-method 中,您正在创建一个对象:
Tester ot = new Tester();
你是对的,如果你自己没有显式定义构造函数,编译器会通过 super()
调用生成一个隐式默认构造函数。它看起来像这样:
public Tester() {
super();
}
这意味着它会尝试调用您的构造函数 YouArePublic() { super(); }
,它具有默认可见性,也就是包私有。由于 YouArePublic
在另一个包中,因此无法从 Tester
.
您只能对静态方法进行静态调用。对于那个初始化是不需要的。但是在这里您没有进行静态调用,并且您的父 class 方法不是静态的。为此,您应该如下修改您的父级 class。(但仅此一项不足以编译 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);
}
}
异常原因: 当创建子 class 的对象时,首先调用父 class 的构造函数,然后调用子 class.For 的构造函数编译器,您的代码与下面显示的代码相同。
class Tester extends YouArePublic {
public Tester(){
super();
}
public static void main(String args[]) {
Tester ot = new Tester();
ot.displayMessage();
}
}
在您的情况下,无法完成对超级构造函数的调用,因为父构造函数的可见性为 'default',并且仅对同一包中的 classes 可见。
如果您不向父级添加任何构造函数 class 编译器会假定它具有 public 默认构造函数。您通过创建自己的构造函数来限制这一点。