6

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

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

基类:

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
 }
}

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

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

4

6 回答 6

10

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

最后一点是关键——如果你写过

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

那么这将起作用,因为您正在更改自己类的受保护成员(通过继承存在于该类中)。但是,在您的情况下,您正在尝试更改不同包中不同类的受保护成员。因此,您被拒绝访问也就不足为奇了。

于 2010-06-30T11:23:44.700 回答
3

如果是类成员,protected则有两种情况:

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

I. 同一个包:
- 可以通过继承访问
- 可以通过创建父类的实例来访问
II。不同的包:
-只能通过继承访问

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

在此处输入图像描述

资料来源:SCJP 书籍。

于 2015-03-24T06:08:31.437 回答
3

Java教程说:

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

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

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

于 2010-06-30T11:28:39.983 回答
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);
    }
}

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

于 2010-06-30T11:30:21.550 回答
0

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

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

 public void test(){

     intg = 1;

 }
}
于 2014-06-06T12:05:48.130 回答
0

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

您可以尝试以下方法。

package secondary;

import com.core.MyCollection;

public class MyCollection2 extends MyCollection{ 

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

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

于 2010-06-30T11:26:25.140 回答