为什么 Java 构造函数必须是 public 或 protected 才能将类扩展到其包之​​外?

发布于 2024-12-20 20:39:58 字数 824 浏览 2 评论 0原文

以下是我的 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 类的构造函数设置为 publicprotected 那么代码可以正常编译,不会出现错误。

那么为什么构造函数有必要是公共的或受保护的,而不仅仅是默认访问权限呢?

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

十年九夏 2024-12-27 20:39:58

如果您想在其包之外扩展一个类,它必须有一个 publicprotected 的构造函数,因为在 Java 中,每个构造函数都必须调用其超类的构造函数。

因此,每个没有 this() 的构造函数中都会有一个隐含的 super() 调用,或者显式调用 super()作为其第一个声明。如果你根本不指定构造函数,Java 将添加一个默认的无参数构造函数,所以实际上你的代码看起来像这样:

public class UsingProtectedCon extends ProtectedConstructor {
    public UsingProtectedCon() {
        super();
    }

    public static void main(String... a) {   
    }
}

换句话说,你的代码无法编译,因为调用 super() 无法解析。

If you want to extends a class outside its package it must have a constructor that is public or protected 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 have this() or an explicit call to super() 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:

public class UsingProtectedCon extends ProtectedConstructor {
    public UsingProtectedCon() {
        super();
    }

    public static void main(String... a) {   
    }
}

So in other words your code is failing to compile because the call to super() in the default constructor cannot be resolved.

绝情姑娘 2024-12-27 20:39:58

构造函数是类的成员,如fieldmethod,因此访问修饰符适用于它

当您在 B 中扩展类 A 时,它以同样的方式适用于类的所有成员, A 是默认值构造函数将从 B 的构造函数隐式调用(如果您不调用任何重载的构造函数)

constructor is a member of class like field and method so access modifier applies to it in the same manner it apples to all the member of class

when 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)

浪推晚风 2024-12-27 20:39:58

在您的类中 ProtectedConstructor 是使用 Package-Private 访问权限定义的
这意味着在包外部,即使从 ProtectedConstructor 类扩展的类也看不到它,

而是使用“protected”访问修饰符定义构造函数,然后就完成了:

 package protectCon;

public class ProtectedConstructor{
    public int nothing;
    protected ProtectedConstructor(){
        nothing = 0;
    }
}

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:

 package protectCon;

public class ProtectedConstructor{
    public int nothing;
    protected ProtectedConstructor(){
        nothing = 0;
    }
}
强者自强 2024-12-27 20:39:58

您的构造函数不是公开的。默认范围是包私有的。

Your constructor is not public. Default scope is package-private.

你是暖光i 2024-12-27 20:39:58

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

浮光之海 2024-12-27 20:39:58

为了避免所有混乱,请这样做。
封装保护Con;

public class ProtectedConstructor{
    public int nothing;
    public ProtectedConstructor(){
        nothing = 0;
    }
}


package other;

import protectCon.ProtectedConstructor;
public class UsingProtectedCon extends ProtectedConstructor{   //**Line 4**

    public UsingProtectedCon(){
      super();
      }


  public static void main(String... a){   
    }
}

to avoid all confusion do it like this.
package protectCon;

public class ProtectedConstructor{
    public int nothing;
    public ProtectedConstructor(){
        nothing = 0;
    }
}


package other;

import protectCon.ProtectedConstructor;
public class UsingProtectedCon extends ProtectedConstructor{   //**Line 4**

    public UsingProtectedCon(){
      super();
      }


  public static void main(String... a){   
    }
}
花伊自在美 2024-12-27 20:39:58

您可以拥有公共的、受保护的(供内部使用)甚至私有的构造函数。

一个简单的例子是 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 constructor public as if often the case. ;) hint: it is the same as protected.

尹雨沫 2024-12-27 20:39:58

如果孩子有父级中私有的构造函数,我们可以使用该构造函数创建子级的实例并将其转换为父级的类型。
因此,为了防止这个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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文