任何人都可以解释我这里发生的事情:java中的“protected”修饰符

时间:2015-02-17 15:52:06

标签: java inheritance protected

我学到的一件事是java中的private并不意味着与C ++中的相同。 java中的private是基于类的,而不是基于对象的。 即我可以使用“对象点符号”直接访问另一个对象私有成员,前提是我在该对象的类中这样做。

然而,protected并不是那么清楚。 我们必须在此处考虑两个包:pack1pack2
我们在Alpha包中声明了类Betapack1 并声明AlphaSub扩展Alpha pack1Gamma 扩展Alpha pack2 。 !

enter image description here

以下是类代码,我在此处仅包含与问题相关的类:AlphaAlphaSubGamma

package pack1;

public class Alpha{
  private int alphaPrivate;
  public int alphaPublic;
  protected int alphaProtected;
  int alphaPP;

  protected int alphaProtected(){
    return 1;
  }
  private int alphaPrivate(){
    return 1;
  }
}

package pack2;

import pack1.Alpha;
public class AlphaSub extends Alpha{
    int alphasubPP;
    private int alphasubPrivate;
    protected int alphasubProtected;
    public int alphasubPublic;

    public void meth() throws CloneNotSupportedException{
        new AlphaSub().alphaProtected(); //OK
        new Gamma().alphaProtected(); /*COMPILE ERROR. */

    }
}

显然即使AlphaSub和Gamma都从alphaProtected()继承Alpha,也无法从AlphaSub调用Gamma继承的alphaProtected()。 如果这样的情况是只能从该类中调用类的受保护方法,那么调用clone [来自Object类的每个类继承的{{1}}是不可能的?

有人可以澄清一下吗?

1 个答案:

答案 0 :(得分:1)

JLS 6.6.2.1.中涵盖了您所体验到的内容:

  

6.6.2.1。访问受保护的会员

     

设C是声明受保护成员的类。访问是   只允许在C的子类S的主体内使用。

     

此外,如果Id表示实例字段或实例方法,则:

     
      
  • 如果访问是通过限定名称Q.Id或方法引用表达式Q :: Id(第15.13节),其中Q是ExpressionName,那么   当且仅当表达式Q的类型是S时才允许访问   或S的子类。

  •   
  • 如果访问是通过字段访问表达式E.Id,或方法调用表达式E.Id(...),或方法引用表达式E ::   Id,其中E是主表达式(第15.8节),然后是访问权限   当且仅当E的类型是S或S的子类时才被允许。

  •   
  • 如果访问是通过方法引用表达式T :: Id进行的,其中T是ReferenceType,那么当且仅当   type T是S或S的子类。

  •   

你是对的,如果你用new Gamma().alphaProtected();替换new Gamma().clone();,你将得到相同的编译错误。