java - 使用基类实例在派生类中访问的受保护成员

时间:2010-06-30 11:09:02

标签: java protected access-control

我在派生类中创建了基类的实例,并尝试访问受保护的成员。

我可以直接访问派生类中的受保护成员,而无需实例化基类。

基类:

package com.core;

public class MyCollection {

      protected Integer intg;
}

同一个包中的派生类 -

package com.core;

public class MyCollection3 extends MyCollection { 

 public void test(){

  MyCollection mc = new MyCollection();
  mc.intg=1; // Works
 }
}

不同包中的派生类 -

package secondary;

import com.core.MyCollection;

public class MyCollection2 extends MyCollection{ 

 public void test(){
  MyCollection mc = new MyCollection();
  mc.intg = 1; //!!! compile time error - change visibility of "intg" to protected
 }
}

当派生类也在同一个包中但是当派生类在不同的包中时,如何使用基类实例访问派生类中基类的受保护成员?

如果我将受保护的成员标记为“静态”,那么我可以使用驻留在不同包中的派生类中的基类实例来访问基类的受保护成员。

6 个答案:

答案 0 :(得分:10)

你是对的,你做不到这一点。您无法访问该字段的原因是您与该类不在同一个包中,您也无法访问同一类的继承成员

最后一点是关键点 - 如果你写了

MyCollection2 mc = new MyCollection2();
mc.intg = 1;

然后这将有效,因为您正在更改您自己的类(通过继承存在于该类中)的受保护成员。但是,在您的情况下,您尝试在其他包中更改不同类的受保护成员。因此,如果你被拒绝进入,就不足为奇了。

答案 1 :(得分:3)

Java tutorial说:

  

protected修饰符指定只能在其自己的包中访问该成员(与package-private一样),此外,还可以在另一个包中通过其类的子类访问该成员。

在您的情况下,您正在访问另一个对象中的变量。巧合的是,它有一个与当前类相同的类,但是可见性检查不会检查它。

所以,第二次拒绝访问,因为你在不同的包中,并且第一次获得访问权限,因为你在同一个包中(而不是因为它是一个子类)

答案 2 :(得分:3)

如果一个班级成员是protected,则有两种情况:

  
      
  1. 如果子类在同一个包中
  2.   
  3. 如果子类在不同的包中
  4.         

    予。相同的包装:
       - 可以通过继承访问
       - 可以通过创建父类的实例来访问   II。不同的包装:
       - 只能通过继承访问

有关所有用例,请参阅下表:

enter image description here

答案 3 :(得分:1)

简而言之,这不太可能。你似乎应该重新考虑你的设计。

然而,如果你确定这是你想做的事情,那就有一个解决方法。您可以将受保护的方法添加到MyCollection,其中包含一个实例并代表您设置intg的值:

package com.core;

public class MyCollection {

    protected Integer intg;

    protected void setIntg(MyCollection collection, Integer newIntg) {
        collection.intg = newIntg;
    }
}

现在您的子类可以访问此方法:

package secondary;

import com.core.MyCollection;

public class MyCollection2 extends MyCollection{ 

    public void test(){
        MyCollection mc = new MyCollection();
        setIntg(mc, 1);
    }
}

但请注意,这是一种非常奇怪的做法。我再次建议你在沿着这条路走下去之前需要重新考虑你的设计。

答案 4 :(得分:0)

根据Java的成员可访问性规则,您无法在不扩展它的情况下访问类的受保护成员。

您可以尝试以下操作。

package secondary;

import com.core.MyCollection;

public class MyCollection2 extends MyCollection{ 

 public void test(){
  intg = 1; 
 }
}

尝试分配值,而不是创建新实例。它会起作用。

答案 5 :(得分:0)

如果使用类MyCollection的新对象访问,则无法访问派生类(位于不同包中)中的受保护变量。 你可以写intg = 1;直接不做(新的MyCollection) 像这样:

package secondary;
import com.core.MyCollection;       
public class MyCollection2 extends MyCollection{ 

 public void test(){

     intg = 1;

 }
}