Java 受保护的can';t访问不同的包子类为什么?

Java 受保护的can';t访问不同的包子类为什么?,java,Java,错误:m1()在 当我尝试使用超类引用变量(A obj=new B())时 这是pkg1包中的第一个类 package pkg1; public class A { protected void m1() { System.out.println("protected method"); } } 这是第二个类,位于导入pkg1的另一个包pkg2中 package pkg2; import pkg1.A; public class B extends A {

错误:
m1()在

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

这是pkg1包中的第一个类

package pkg1;
public class A {
    protected void m1() {
        System.out.println("protected method");
    }
}
这是第二个类,位于导入pkg1的另一个包pkg2中

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();
    }
}

受保护的关键字意味着您可以从子类访问受保护的定义数据。在本例中,您尝试从非子静态上下文访问受保护的数据。您可能应该尝试以下方法:

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();
    }
}

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

我觉得您仍然对为什么受保护的m1()不可见有点困惑

您知道
main
B
中的一个方法,
B
a
的一个子类,因此您觉得它应该是可访问的

键为
obj
被转换为
A
类型。然后,您尝试从
B
中的静态上下文调用实例方法
m1
(请参阅上面的链接了解这一点的重要性)。根据类别
A
定义,
m1
可通过以下方式访问:

  • 类定义本身在其自身的给定实例上
  • //范例 包装pkg1; 公共C类{ 受保护的空m1(){ System.out.println(“受保护方法”); } 公共静态无效调用M1(C实例FC){ anistanceofc.m1(); } } 包装pkg2; 进口pkg1.C; 公共类D扩展C{ @凌驾 公共空间m1(){ 系统输出打印项次(“覆盖m1”); } 公共静态void main(字符串ar[]{ C obj=新的D(); C.callM1(obj);//输出将是“覆盖m1” } }
  • 类本身和子类的实例方法(当然)
  • //范例 包装pkg1; 公共C类{ 受保护的空m1(){ System.out.println(“受保护方法”); } 公共空间m2(){ m1();//调用实例方法m1 } 公共静态无效调用M1(C实例FC){ anistanceofc.m2(); } } 包装pkg2; 进口pkg1.C; 公共类D扩展C{ @凌驾 公共空间m1(){ 系统输出打印项次(“覆盖m1”); } 公共空间m3(){ //super.m2() m2();//调用超类方法 } 公共静态void main(字符串ar[]{ D obj=新的D(); D.m3();//输出“覆盖m1” } }
    您正在尝试访问
    obj.m1()
    并且
    obj
    属于
    A
    类型。所以……的确如此。请解释一下你为什么希望这样做。(以后,请多注意代码格式。我现在已经修好了,但以前很乱。)@denys Seguret、@jon Skeet if I'm worn java提供了动态方法分派机制,所以我想我可以访问m1()使用类型A的引用变量从A重写的方法。@SeniorJD当我在类B中扩展A时,这意味着B是类A的子类。但是
    main
    method实际上不是B对象的一部分。main方法如何不是B对象的一部分?你会对类和对象的概念感到困惑
    main
    是B类的一部分,但不是B对象的一部分。@我从来没有想过这样的静态方法,但你是对的。 //example package pkg1; public class C { protected void m1() { System.out.println("protected method"); } public static void callM1(C anInstanceOfC){ anInstanceOfC.m1(); } } package pkg2; import pkg1.C; public class D extends C { @Override public void m1() { System.out.println("override m1"); } public static void main(String ar[]) { C obj=new D(); C.callM1(obj);//output would be "override m1" } } //example package pkg1; public class C { protected void m1() { System.out.println("protected method"); } public void m2() { m1();//call to instance method m1 } public static void callM1(C anInstanceOfC){ anInstanceOfC.m2(); } } package pkg2; import pkg1.C; public class D extends C { @Override public void m1() { System.out.println("override m1"); } public void m3() { //super.m2() m2();//call to superclass method } public static void main(String ar[]) { D obj=new D(); D.m3(); // output "override m1" } }