【问题标题】:protected can't access in different package subclass why?protected 不能在不同的包子类中访问为什么?
【发布时间】:2016-01-13 15:10:32
【问题描述】:

错误:m1() has protected access in A

当我尝试使用超类引用变量 (A obj=new B())

这是包 pkg1 中的第一个类;

package pkg1;
public class A {
    protected void m1() {
        System.out.println("protected method");
    }
}

这是第二个类,它在另一个包 pkg2 中导入 pkg1;

package pkg2;

import pkg1.A;
public class B extends A {
    @Override
    protected void m1() {
        System.out.println("override m1");
    }

    public static void main(String ar[]) {
        A obj=new B();
        obj.m1();
    }
}

【问题讨论】:

  • 您正在尝试访问obj.m1(),而obj 的类型为A。所以...
  • 确实如此。请解释为什么您期望它会起作用。 (而且以后请多注意代码格式,我现在已经修好了,但之前是一团糟。)
  • @denys Seguret ,@ jon Skeet 如果我没有穿g java 提供了动态方法分派的机制,所以我认为我可以访问 m1() 方法,该方法通过使用引用从 A 覆盖A 类型的变量。

标签: java


【解决方案1】:

我觉得您仍然对为什么看不到 protected m1() 感到有些困惑。

您知道mainB 中的一个方法,而BA 的子类,因此您觉得它应该是可访问的。

键是obj 被强制转换为A 类型的解释。然后你尝试从Bstatic 上下文中调用instance method m1(请参阅上面的this 链接了解为什么这很重要)。按类A 定义,m1 可通过以下方式访问:

  1. 类定义本身在给定实例上。
//例子 包 pkg1; 公共类 C { 受保护的无效 m1() { System.out.println("受保护的方法"); } 公共静态无效调用M1(C anInstanceOfC){ anInstanceOfC.m1(); } } 包pkg2; 导入pkg1.C; 公共类 D 扩展 C { @覆盖 公共无效 m1() { System.out.println("覆盖 m1"); } 公共静态无效主要(字符串ar []){ C obj=新的 D(); C.callM1(obj);//输出将是“覆盖 m1” } }
  1. 类自身和子类的实例方法(当然)。
//例子 包 pkg1; 公共类 C { 受保护的无效 m1() { System.out.println("受保护的方法"); } 公共无效 m2() { m1();//调用实例方法m1 } 公共静态无效调用M1(C anInstanceOfC){ anInstanceOfC.m2(); } } 包pkg2; 导入pkg1.C; 公共类 D 扩展 C { @覆盖 公共无效 m1() { System.out.println("覆盖 m1"); } 公共无效 m3() { //super.m2() m2();//调用超类方法 } 公共静态无效主要(字符串ar []){ D obj=新的 D(); D.m3(); // 输出“覆盖 m1” } }

【讨论】:

    【解决方案2】:

    protected 关键字意味着您可以从子类访问受保护定义的数据。例如,您尝试从非子静态上下文访问受保护的数据。你应该试试这个:

    package pkg2;
    
    import pkg1.A;
    public class B extends A {
        @Override
        public void m1() {
            System.out.println("override m1");
        }
    
        public static void main(String ar[]) {
            B obj=new B();
            obj.m1();
        }
    }
    

    【讨论】:

    • @SeniorJD 当我在 B 类中扩展 A 时,这意味着 B 是 A 类的孩子。
    • 但是main方法实际上并不是B对象的一部分。
    • main方法怎么不是B对象的一部分?
    • 您对类和对象的概念感到困惑。 main 是 B 类的一部分,但不是 B 对象的一部分。
    • @SeniorJD 我从来没有真正想过这样的静态方法,但你是对的。 Difference between Static methods and Instance methods
    【解决方案3】:

    m1() 的访问级别受到保护。受保护的方法只能由子类或同一包中的其他类访问。从您的 static 'main' 方法中,您不能调用不同包中类的受保护 instance 方法。如果 B 类与 A 类在同一个包中,那么您将不会出错,并且您的代码可以正常工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-28
      • 2017-06-04
      • 2013-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-06
      • 2014-03-28
      相关资源
      最近更新 更多