java protected为什么这是通过非继承工作?

时间:2013-02-18 20:11:41

标签: java protected

我显然忽略了这一点,但是给出了:

package a;
public class Class1 {
    protected int a=1;
}

package b;
import a.*;

public class Class2 extends Class1 {
    Class2() {
        Class1 c1=new Class1();
        Class2 c2=new Class2();
        System.out.println(a);     //1
        System.out.println(c1.a);  //2
        System.out.println(c2.a);  //3
    }
}

我知道// 1由于通过继承使用而很好而且// 2失败,因为它不是通过继承访问,但为什么// 3也可以呢?我认为变量a是通过一个新对象访问的,并且存在于Class1中?

感谢。

4 个答案:

答案 0 :(得分:4)

由于Class2的任何对象都是Class1,因此它可以访问范围为Class 1default和{protected的所有public个成员变量{1}}。

此外,尝试通过处理您用于使用范围/不一致的类的对象来了解范围和继承规则并不是一个好主意,因为它的工作方式与通过第三方不同(这是最常见的用途。)

例如,允许这样做:

public class Something {
   private int something;

   public int stealSomething(final Something otherthing) {
       return otherthing.something;
   }
} 

尝试创建第三个类,它不在您用来测试的类的层次结构中。

答案 1 :(得分:4)

当您在其类中操作对象时,您可以完全访问其所有属性,包括私有属性。由于c2Class2的实例,并且您在Class2代码中操作它,因此您可以看到受保护的属性。

答案 2 :(得分:3)

  

为什么// 3也可以?

为什么不应该没问题呢?鉴于Class2Class1的子类,因此protected的{​​{1}}字段可通过Class1的实例访问。这就是你在这里所做的。 Class2c2的一个实例,Class2字段可见。

注意: 任何直接子类都可以访问受保护的成员,无论是在同一个包中还是在不同的包中。

  

我认为变量a是通过新对象访问的

是的,那是真的。

  

和a位于Class1?

这在这里真的没关系。只要a实例可以访问a,它就是有效的。

仅供参考,您的代码将死于Class2。你需要照顾它。

答案 3 :(得分:1)

我不明白这个问题。

Class1有一个名为'a'的变量。由于它是“受保护的”,因此该变量在Class1的任何对象和扩展Class1的类的任何对象中都是可见的。

如果'a'是私有的,那么在扩展Class1的类的对象中就不会以这种方式显示。