【问题标题】:why an instance member in super class cannot accessed by Super class reference in Subclass in another package为什么超类中的实例成员不能被另一个包中的子类中的超类引用访问
【发布时间】:2016-04-10 14:21:03
【问题描述】:

我在PackageOne 中有一个超类 A,在PackageTwo 中有一个子类 B。

package PackageOne;

public class A {        
protected number = 0;        
}

二等奖来了

package PackageTwo;

public class B extends A {
    public static void main(String args[]) {
       A a = new A();
       System.out.println(a.number);// Here is the error occurs        
    }        
}

错误是The field Person.name is not visible

据我所知,受保护的成员可以通过超类引用访问,但为什么会发生错误。

【问题讨论】:

  • 在这种情况下,B 甚至不是A 的子类。为什么您期望可以访问? (另外,以后在格式化您的帖子时请多加注意。这次我已经修复了它,但在您发布之前请先查看预览。)
  • 我看不到任何继承(编辑前)
  • @maskacovnik 我现在编辑了我的代码检查
  • “字段 Person.name”在哪里?通常不存在的东西是不可见的。
  • @MikeCAT OP 显然的意思是“字段 A.number 不可见”,而是粘贴了实际错误而不是他的示例中发生的错误。

标签: java


【解决方案1】:

如果您在不同的包中,则无法访问另一个实例的字段。您只能访问自己内部的字段。

班级A:

package a;

public class A {
    protected int i;
}

班级B:

package b;

public class B extends A {

    void m() {
        A a = new A();
        System.out.println(a.i); // error here!

        System.out.println(i);   // but no error here
    }
}

如果AB 在同一个包中,则不会有任何错误。

【讨论】:

    【解决方案2】:

    Controlling Access to Members of a Class

    protected 修饰符指定该成员只能在其自己的包中访问(与 package-private 一样),此外,它的类在另一个包中的子类也可以访问。

    因为它是protected 成员。你需要extend(继承)类来访问另一个包中类的protected成员。

    不要通过A 访问它,而是通过B 访问它。一旦你扩展了A 类,它就成为B 类的一部分。您无法使用A 的引用访问它。

    public class B extends A {
      public static void main(String args[]) {
        B b = new B();  // create the instance of B.
        System.out.println(b.number);  // access via the b.
      }
    }
    

    您还缺少 A 类中的数据类型:

    public class A {
      protected int number = 0;
    }
    

    在同一个包中,您可以使用实例引用来引用成员。检查以下代码:

    package PackageOne;
    
    public class C {
      public static void main(String[] args) {
        A a = new A();
        System.out.println(a.number); // this works.
      }
    }
    

    【讨论】:

    • 如果 AB 在不同的包中,这将不起作用,正如 OP 在他的问题中所说的那样。
    • @ThiagoPorciúncula 我明白了。并更新了答案。
    • 现在它可以工作了,尽管这与 OP 的情况有点不同。
    • @ThiagoPorciúncula 不一样,因为OP试图做的是完全错误的java编译错误。
    • 是的。这基本上就是我在回答中写的。
    【解决方案3】:

    受保护的方法只能通过包外的子类中的继承来访问。因此,第二种方法 tryMeProtected();有效。

    下面的代码不会编译,因为我们没有调用受保护方法的继承版本。

    Example
    Class1 c = new ClassA();
    c.tryMeProtected(); // ERROR: tryMeProtected() has protected access in ClassA
    

    关注This stack link了解更多详情。

    【讨论】:

      【解决方案4】:

      继承不是这样工作的。您不能通过创建一个类的实例来使一个类成为另一个类的子类。

      你必须extend它。

      public class B extends A
      

      这将允许您访问protected 字段。但是,您必须import PackageOne.A 才能执行此操作。

      编辑

      请参阅@David Segonds 的this SO 回答,了解这些关键字的工作原理

                  | Class | Package | Subclass | World
      ————————————+———————+—————————+——————————+———————
      protected   |  y    |    y    |    y     |   n
      

      您必须是子类或在同一个包中才能访问这些属性。

      来自official documentation

      protected 修饰符指定该成员只能在其自己的包中访问(与 package-private 一样),此外,它的类在另一个包中的子类也可以访问。

      【讨论】:

      • @ThiagoPorciúncula 感谢您引起我的注意。查看我编辑的答案
      猜你喜欢
      • 1970-01-01
      • 2022-11-30
      • 2020-10-30
      • 2017-06-04
      • 2019-05-28
      • 2019-05-12
      • 1970-01-01
      • 2016-03-27
      • 2012-12-01
      相关资源
      最近更新 更多