【问题标题】:Why can't I access a protected variable in Java this way?为什么我不能以这种方式访问​​ Java 中的受保护变量?
【发布时间】:2023-03-12 02:36:01
【问题描述】:

我有一个这样定义的类:

package prueba;

public class OtraClase {

[...]

protected int num3;

[...]

另外一个类是这样定义的:

package otro;

import prueba.*;

public class OtraClaseMas extends OtraClase{

但是,如果在最后一课中我创建了一个 OtraClase 对象,我将无法执行以下操作:

createdObjectOfOtraClase.num3=1;

我认为根据文档我应该能够做到,here。它说受保护的修饰符允许另一个包中其类的子类访问。尽管我看到它,但我认为它只是另一个包中它的类的子类。

我是不是误会了什么?

编辑:我要么使用类的构造函数,要么使用另一个不同的函数,但它在任何地方都不起作用。

构造函数代码:

public OtraClaseMas(int num, int num2,int num3)
{
    super(num, num2,num3);      
    OtraClase oc=new OtraClase(1,1,1);
   //oc.num3=1; This doesn't work
}

方法代码:

public void foo()
{
    OtraClase oc=new OtraClase(1,1,1);
    //oc.num3=1; This doesn't work

}

【问题讨论】:

  • 你能告诉我们createdObjectOfOtraClase.num3=1;的电话在哪里吗?
  • 我无法重现该问题。如果对createdObjectOfOrtaClase.num3 = 1 的调用发生在OrtaClaseMas 内,它应该可以工作。
  • 你有没有 - 有没有机会 - 将 num3 声明为 final

标签: java protected


【解决方案1】:

关于保护类:

最简单的答案是,您正在扩展的 基类 (SuperClass) 存在于它自己的包中(比如说在火星行星的卧室中),它的受保护的领域(比方说激光枪)。

当您通过继承(即扩展)到不同的包和类(假设地球上的一个办公室)来实现这个类时,您正在创建一个从地球到火星的门户,再到激光枪的一个受保护门户中存在于只有办公室,只有这个门户才能给你枪。

因此地球上的外星人卧室(基类)(在新包中)不知道也不能将您引荐给激光枪,因为他们没有办公室的门户,因此您不能问他们向您介绍激光枪。但您可以询问办公室以及任何创建办公室门户的机构以供参考。

所以现在你有枪了,可以皮尤了!皮尤!

注意:如果您在同一个包中,则不需要门户(包私有/默认)

【讨论】:

    【解决方案2】:

    所以问题是,如果您想访问父级的 protected 变量,则不能使用引用(正如您在 foo()OtraClaseMas() 中尝试的那样)。文档试图说明的是,如果您愿意,可以直接将变量用作类变量,如下所示-

    package otro;
    import prueba.*;
    
    public class OtraClaseMas extends OtraClase{
        public void foo()
        {
            OtraClase oc=new OtraClase(1,1,1);
            //oc.num3=1; This doesn't work
            num3 = 1; //  this works!
        }
    }
    

    但是,如果引用是在与父类相同的包中创建的(在您的情况下为 prueba),则可以访问 protected 变量。

    【讨论】:

      【解决方案3】:

      protected 变量可以从同一个包或派生类访问,就像它们访问自己的成员一样,但是如果您在超类的包之外创建超类的实例,您将不会即使您正在扩展同一个超类,也能够访问它

      package packageA;
      public class ClassA {
          protected int variableA;
      }
      
      package packageA;
      public class ClassC {
          public void setVariableA() {
              ClassA classA = new ClassA();
              classA.variableA = 1; // OK
          }
      }
      
      package packageB;
      public class ClassB extends ClassA {
          public void setVariableA() {
              ClassA classA = new ClassA();
              variableA = 1; // OK
              classA.variableA = 1;// this wont work
          }
      }
      

      【讨论】:

      • 猜猜 java 文档不正确...很高兴知道。谢谢。
      • 文档没问题,问题是在派生类 OtroClaseMas 中,它位于不同的包中,您正在创建超类的新实例并尝试使用它访问超类的变量新实例,这是不允许的,请检查我添加的代码示例,希望它能让你更清楚
      • 所以总之它必须在同一个包中
      【解决方案4】:

      你确定你正在正确初始化对象吗,因为下面的工作非常好

      public class A {
          protected int x;
      }
      
      
      public class B extends A{
      
      }
      
      
      
      
      public class Test {
          public static void main(String[] args) {
              A a= new A();
      
              a.x=0;
      
              B b=new B();
              b.x=1;
      
              A c=new B();
      
              c.x=2;
              }    
      }
      

      【讨论】:

      • 您误解了这个问题。他问的是我们在不同包中创建子类时的情况。
      猜你喜欢
      • 2011-10-06
      • 2010-10-08
      • 2010-10-28
      • 2010-12-09
      • 1970-01-01
      • 1970-01-01
      • 2013-06-19
      • 2013-11-25
      • 1970-01-01
      相关资源
      最近更新 更多