从超类访问私有变量(JAVA)

11

好的,那么我整个学期都学习了Java,并且认为自己对继承和超类/子类有清晰的理解。今天我们被分配了一个制作名为enemy的超类的作业,其中包含不同类型敌人的子类。我做得很好,我的所有子类都正常工作,但当我回来阅读我们必须遵循的指南时,我发现了这句话:

“超类的所有成员变量必须是私有的。必须通过子类中的受保护方法访问任何变量。”

根据我的学习,这对我来说毫无意义。如果一个变量在超类中是私有的,那么即使从子类中也无法访问。最后谈到的关于在子类中使用受保护方法也对我毫无意义。这如何帮助和/或允许任何方式访问超类?

根据我对继承所学的内容,以下是我认为正确的:

                Access Levels
 Modifier    Class  Package Subclass    World
 public        Y      Y        Y        Y
 protected     Y      Y        Y        N
 no modifier   Y      Y        N        N
 private       Y      N        N        N

如果我对这里的某些事情理解有误,请解释一下!如果是我没有正确理解,我不想因此质疑授课教师给我们提供了错误的指导。


2
你说得对,这些指令措辞很糟糕。听起来好像要求你通过“子类中定义的protected方法”访问私有变量,但实际上是通过“子类中调用的protected方法”访问。 - yshavit
6个回答

20

这部分

Any access to an a variable must be done through protected methods in the sub classes.

这只是意味着子类必须调用在超类中定义的受保护方法。由于这些方法是受保护的,它们可以被子类访问。

首先,您会像这样定义一个基类:

public class Base {

    private int x;  // field is private

    protected int getX() {  // define getter
        return x;
    }

    protected void setX(int x) {  // define setter
        this.x = x;
    }
}

然后您可以在子类中像这样使用它:

class Child extends Base{

    void foo() {
        int x = getX(); // we can access the method since it is protected.
        setX(42);  // this works too.
    }
}

为什么不直接将变量设置为protected,而要费心去写protected的getter和setter呢?如果你有10个不同的变量,我认为这是浪费时间。 - Sahand
1
是的,大多数情况下明智的做法是使用受保护的变量。但问题是关于一个具体的任务,指导方针规定使用私有变量并通过getter和setter进行访问。提问者对指南和Java语法的含义感到困惑,这就是答案所回答的内容。 - Cyrille Ka

2

当你继承其他类时,不能直接访问私有属性。因此,如果你有一个名为“A”的类和另一个名为“B”的类,并使B扩展A,则B无法访问A的私有属性。

可以将其视为一种保护方式。这样,你可以在“A”类中编写一些属性,你不希望其他类通过继承来访问它。

“B”类只能直接访问“A”类中的公共、受保护和默认属性。但是,如果你想出于任何原因访问“A”类中的私有属性,可以在“A”类中编写一个方法来返回该属性。

public class A{
    private int foo;
    public int getFoo(){
       return this.foo;
    }
}

public class B extends A{
    public void doSomething(){
       getFoo(); //return the private foo attribute of superclass
    }
}

2

这句话可能表述不太准确,但从我的理解来看,它对我来说是完全有意义的:
1. 超类拥有私有字段和访问它们的受保护方法。
2. 子类通过使用那些方法来访问这些字段。


2

这些只是任务的限制,而不是Java本身。您可以给超类添加受保护的数据成员,然后直接从子类访问这些成员。然而,教授可能希望教你如何通过超类保护其数据成员,以免被子类直接访问,而受保护的方法就是一种实现方式。


1
你的想法是正确的,从字面上讲,你无法访问超类的私有字段。你的任务使用了不完全严格但在Java术语中通常使用的措辞:所谓的“getter”方法,也称为“访问器”方法,被视为“访问字段”,尽管严格来说,它们只是返回字段的当前值——这绝对不同于访问字段本身。你只需要习惯Java术语中的这种(以及更多)约定即可。

0
package com.action.product;

public class ProductAction{
  public static String strCategoryName;

  public String getStrCategoryName() {
    return strCategoryName;
  }
  public void setStrCategoryName(String strCategoryName) {
    this.strCategoryName = strCategoryName;
  }

}

-----------------------------------------------------------------------

package com.DAO.product;

public class ProductDAO extends ProductAction {

   @SuppressWarnings("static-access")
   public String addnewProductValidation(){
       System.out.println("======through_name======="+super.strCategoryName);

       System.out.println("======through_getters======="+super.getStrCategoryName());

   }
}

可以将变量初始化为静态的。无需创建对象。

1
这与问题有何关联,该问题询问“如何从子类正确访问超类的私有字段”? - pinpinokio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接