Java Eclipse在另一个包中的子类中尝试使用受保护的构造函数时显示错误

Java Eclipse在另一个包中的子类中尝试使用受保护的构造函数时显示错误,java,inheritance,constructor,package,protected,Java,Inheritance,Constructor,Package,Protected,你好,Stackoverflow社区:-] 我是一名新成员,首先我要感谢您提供的非常有用的建议和更正。由于我是法国人,如果我的英语不完美,请原谅我 这里是我的问题:我目前正在学习Java编程语言,我想测试一些继承的东西。如果我理解正确,声明为protected的字段可以被声明受保护字段的类所在的包中的类访问,也可以被其所有子类访问,无论它们是否在同一包中 所以,我做了这4节课来测试这个。我有一个名为“package1”的包,其中包含类a和C。我还有一个名为“Package2”的包,其中包含类A2

你好,Stackoverflow社区:-]

我是一名新成员,首先我要感谢您提供的非常有用的建议和更正。由于我是法国人,如果我的英语不完美,请原谅我

这里是我的问题:我目前正在学习Java编程语言,我想测试一些继承的东西。如果我理解正确,声明为
protected
的字段可以被声明受保护字段的类所在的包中的类访问,也可以被其所有子类访问,无论它们是否在同一包中

所以,我做了这4节课来测试这个。我有一个名为“package1”的包,其中包含类a和C。我还有一个名为“Package2”的包,其中包含类A2和C,其中A2扩展了a。两个C类的代码完全相同,只是它们所在的包发生了更改。它们不扩展a

在一个类中,我声明了一些具有不同访问属性的成员,特别是使用
protected
可见性声明的构造函数。这是四个类的代码

包装1,A类:

package package1;

public class A {

    public int a;
    protected int b;
    private int c;
    int d;

    protected static int h = 30;

    protected void aff(){
        System.out.println(h);
    }

    protected A(){
        a = 1;
        b = 2;
        c = 3;
        d = 4;
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub

    }

}
包1,C类:

package package1;

public class C {

    public C(){
        super();
    }

    public void app(){
        A obj = new A(); //////// OK
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub


        A obj = new A(); //////// OK
        obj.aff(); //////// OK

        System.out.println(obj.a);

    }

}
A2类包装2(扩展A):

包装2,C类:

package package2;
import package1.A;

public class C {


    public C(){
        super();
    }

    public void app(){

        A obj = new A(); //////// ERROR
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub


        A obj = new A(); //////// ERROR
        obj.aff(); //////// ERROR

        System.out.println(obj.a);

    }

}
对于package2中的C类,代码
A obj=new A()抛出错误,但package1中的C类不是这样。这是正确的,因为构造函数被声明为受保护的,而package2中的C不是a的子类,而C在package1中。到那一点,我理解

我遇到的问题是代码
a obj=newa()在类A2中:无论编写在哪里,它都会抛出一个错误
构造函数A()不可见
。。。由于类A构造函数被声明为受保护的,为什么我不能在A2类中实例化类型A的对象

当我将构造函数声明为
public
时,它可以正常工作。此外,如果我将A2类放在package1中,让代码保持原样,它也可以工作。似乎只有在构造函数声明为受保护的
时,子类位于同一个包中时,才有可能实例化子类中的对象

但是,正如您所看到的,如果我首先实例化一个A2对象,然后调用类a
protected
aff()方法,那么它就可以工作了,并且受保护的规则也得到了遵守

有人对这个错误有什么解释吗?在其子类中实例化超类的对象时,如果超类构造函数被声明为受保护的
,那么该子类是否始终与其超类位于同一个包中?为什么会这样

或者这必须处理构造函数不是由子类继承的事实吗?但我不明白为什么如果是这样

非常感谢您花时间阅读并回答:-]

请参阅:

对象的受保护成员或构造函数可以从包的外部访问,在包中它只能由负责该对象的实现的代码声明

您的类
A2
不负责
newa()
调用中
A
的实现


也就是说,它不负责
A
实例的实现,而是负责
A2
实例的实现。这很有趣,让我来总结一下。看

protected
可以限定构造函数或类的成员

“成员”包括字段/方法(静态/实例)、嵌套类/接口(静态/内部)


首先,要访问受保护的构造函数/成员,必须可以访问封闭类(例如
a
)。那么,假设情况就是这样--

--包装内--

受保护的构造函数或成员可以在同一包中的任何位置访问

--包装外--

受保护的构造函数只能在子类构造函数中访问,可以是
super()
调用,也可以是匿名类实例化

受保护的静态字段/方法、嵌套类/接口可在子类主体内的任何位置访问


受保护的实例字段/方法更复杂--

  • 受保护的“m”在a类中定义
  • obj.m
    在B类中访问(在A的包之外)
  • obj
    的类型是C
只有当B是A的子类,C是B的子类或C是B时,才会授予访问权
obj.m


始终允许
super.m
;然而,目前尚不清楚JLS如何界定这一问题。似乎应该像对待
this.m
一样对待访问,因此允许访问。

您的问题可能会小得多。请参阅。
protected
很有趣:)看来受保护的构造函数只能从子类构造函数调用。这种缺乏规范阅读的情况是如何成为一个好问题的。我为我的问题的长度道歉,我想让大家尽可能清楚。下一次,我将尝试正确匹配最小、完整和可验证的需求:-]@itwasntme:事实上,我在Java规范中找到了一些解释,但理解起来很糟糕。。。对于我的技能来说,它使用了太普通和复杂的样本,并且使用了太复杂的英语技术演讲。我很困惑,不明白他们想说什么,所以我把我的问题贴在这里。阅读说明书并不总是意味着你清楚地理解它。谢谢你的详细回复!所以,如果我理解正确的话,当我把A2放在和A相同的包中,并尝试在A2的主体中实例化一个A对象时,它起作用的原因是,实际上,从访问权限的角度来看,A2首先被认为是与A--b相同包的一个类
package package2;
import package1.A;

public class C {


    public C(){
        super();
    }

    public void app(){

        A obj = new A(); //////// ERROR
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub


        A obj = new A(); //////// ERROR
        obj.aff(); //////// ERROR

        System.out.println(obj.a);

    }

}
class A {
    protected int f
    protected void m(){}
    protected class X{}
    protected interface Y{}