为什么 Java 构造函数必须是 public 或 protected 才能将类扩展到其包之外?
以下是我的 ProtectedConstructor.java
源代码:
package protectCon;
public class ProtectedConstructor{
public int nothing;
ProtectedConstructor(){
nothing = 0;
}
}
以下是 UsingProtectedCon.java
源代码:
package other;
import protectcon.ProtectedConstructor;
public class UsingProtectedCon extends ProtectedConstructor{ //**Line 4**
public static void main(String... a) {
}
}
当我编译 UsingProtectedCon.java
时,出现错误位于上面所示的第 4 行。它说 ProtectedConstructor() 不是 public ;所以无法在包外访问。
但是,由于我的课程是公共的,我是否应该能够将其扩展到包之外。无论如何,我不会创建它的任何实例。
现在,如果我将 ProtectedConstructor
类的构造函数设置为 public
或 protected
那么代码可以正常编译,不会出现错误。
那么为什么构造函数有必要是公共的或受保护的,而不仅仅是默认访问权限呢?
The following is my ProtectedConstructor.java
source code:
package protectCon;
public class ProtectedConstructor{
public int nothing;
ProtectedConstructor(){
nothing = 0;
}
}
And following is the UsingProtectedCon.java
source:
package other;
import protectcon.ProtectedConstructor;
public class UsingProtectedCon extends ProtectedConstructor{ //**Line 4**
public static void main(String... a) {
}
}
When I compile UsingProtectedCon.java
, I get error at Line 4 shown above. It says that ProtectedConstructor() is not public ; so cannot be accessed outside package.
However, since my class is public, shouldn't I be able to extend it outside package. I am anyway not creating any instance of it.
Now, if I make the constructor of ProtectedConstructor
class as public
or protected
then the code compiles fine with no error.
So then why is it necessary even for the constructor to be public
or protected
, and not just have default access?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
如果您想在其包之外扩展一个类,它必须有一个
public
或protected
的构造函数,因为在 Java 中,每个构造函数都必须调用其超类的构造函数。因此,每个没有
this()
的构造函数中都会有一个隐含的super()
调用,或者显式调用super()
作为其第一个声明。如果你根本不指定构造函数,Java 将添加一个默认的无参数构造函数,所以实际上你的代码看起来像这样:换句话说,你的代码无法编译,因为调用
super() 无法解析。
If you want to extends a class outside its package it must have a constructor that is
public
orprotected
because in Java every constructor must call a constructor from its superclass.Because of this there is an implied
super()
call in every constructor which does not havethis()
or an explicit call tosuper()
as its first statement. And if you don't specify a constructor at all Java will add a default parameterless constructor, so in effect your code looks like this:So in other words your code is failing to compile because the call to
super()
in the default constructor cannot be resolved.构造函数
是类的成员,如field
和method
,因此访问修饰符适用于它当您在 B 中扩展类 A 时,它以同样的方式适用于类的所有成员, A 是默认值构造函数将从 B 的构造函数隐式调用(如果您不调用任何重载的构造函数)
constructor
is a member of class likefield
andmethod
so access modifier applies to it in the same manner it apples to all the member of classwhen you extend the class A in B , A's its default constructor will get called from B's constructor implicitly (if you don't call any of the overloaded constructor)
在您的类中 ProtectedConstructor 是使用 Package-Private 访问权限定义的
这意味着在包外部,即使从 ProtectedConstructor 类扩展的类也看不到它,
而是使用“protected”访问修饰符定义构造函数,然后就完成了:
in your class ProtectedConstructor is defined with Package-Private access
This means that outside the package its not seen even by the classes that extend from your ProtectedConstructor class
Define your constructor with 'protected' access modifier instead and you'll be done:
您的构造函数不是公开的。默认范围是包私有的。
Your constructor is not public. Default scope is package-private.
JLS 6.6.7 回答您的问题问题。如果子类涉及其父类的实现,则子类仅访问其父类的受保护成员。因此,如果父构造函数受保护并且位于不同的包中,则无法在子类中实例化父对象。由于子类的默认构造函数会尝试调用父类构造函数,因此会出现此错误。
请参阅此SO 帖子了解详细信息
JLS 6.6.7 answers your question. A subclass only access a protected members of its parent class, if it involves implementation of its parent. Therefore , you can not instantiate a parent object in a child class, if parent constructor is protected and it is in different package.Since the default constructor of the subclass would try to call parent class constructor ,you got this error.
See this SO Post for details
为了避免所有混乱,请这样做。
封装保护Con;
to avoid all confusion do it like this.
package protectCon;
您可以拥有公共的、受保护的(供内部使用)甚至私有的构造函数。
一个简单的例子是 String,它具有供一般使用的公共构造函数和供内部使用的包本地构造函数。
ObjectOutputStream 类有一个公共构造函数,它接受一个 OutputStream 和一个只能由子类使用的
protected
构造函数。顺便说一句:如果您有一个
abstract
类,那么将构造函数设置为public
是否有意义,就像经常发生的情况一样。 ;) 提示:与protected
相同。You can have constructors which are public, protected (for internal used) and even private.
A simple example is String which has
public
constructors for general use and package-local constructors for internal use.The ObjectOutputStream class has a public constructor which takes an OutputStream and a
protected
constructor which can only be used by a sub-class.BTW: if you have an
abstract
class, does it make sense to make the constructorpublic
as if often the case. ;) hint: it is the same asprotected
.如果孩子有父级中私有的构造函数,我们可以使用该构造函数创建子级的实例并将其转换为父级的类型。
因此,为了防止这个java编译器不允许构造函数具有在父级中私有的构造函数。
If child will have constructor which is private in parent,we can make child's instance with that constructor and cast it to parent's type.
So to prevent this java compiler is not allowing constructor to have constructor which is private in parent.