1

我显然错过了这一点,但给出了:

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 正在通过一个新对象访问,而 a 位于 Class1 中?

谢谢。

4

4 回答 4

4

由于Class2is-a 的任何对象Class1,它都可以访问所有Class 1具有作用域的成员变量defaultprotectedpublic

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

例如,这是允许的:

public class Something {
   private int something;

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

尝试制作第三个类,它不在您用于测试的类的层次结构中。

于 2013-02-18T20:17:46.577 回答
4

当您在其类中操作对象时,您可以完全访问他的所有属性,包括私有属性。作为c2一个实例,Class2并且您正在Class2代码中对其进行操作,您可以看到受保护的属性。

于 2013-02-18T20:18:27.673 回答
3

为什么 //3 也可以?

为什么不应该没问题?鉴于这Class2是 的子类Class1,因此可以通过 的实例访问的protected字段。这就是你在这里所做的。是 的一个实例,并且字段对它是可见的。Class1Class2c2Class2a

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

我认为变量 a 正在通过一个新对象访问

对,那是真的。

并且 a 位于 Class1 中?

这在这里真的不重要。就实例a可访问而言Class2,它是有效的。

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

于 2013-02-18T20:18:11.803 回答
1

我不明白这个问题。

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

如果“a”是私有的,那么它在扩展 Class1 的类的对象中不会以这种方式可见。

于 2013-02-18T20:18:02.277 回答