2

好吧,我必须承认我对 Java 编程很陌生,并且非常犹豫在这里发布问题,因为有很多问题与我的问题相似。我已经查看了这些问题,但我仍然无法理解“受保护”修饰符背后的逻辑是什么。所以我认为最好在这里发布我自己的问题。

这是A包中的类PackOne

package PackOne;

public class A {

    protected void protectedMethod() {
        System.out.println("A's protectedMethod");
    }

}

这是B包中的类PackTwo。但是,它是 class 的子类A

package PackTwo;

import PackOne.A;

public class B extends A {

    public static void main(String[] args) {

        //Test 1 
        protectedMethod(); //error: non-static method protectedMethod()
                           // cannot be referenced from a static context.

        //Test 2
        A instanceofA = new A();
        instanceofA.protectedMethod();//error: protectedMethod() 
                                      //has protected access in PackOne.A
    }

    public void anotherMethodOfB() {

        //Test 3
        protectedMethod();//Pass 
    }

    //Test 4
    A instanceofA = new A();
    instanceofA.protectedMethod();//error: package instanceofA does not existed.
}

请解释为什么只有测试 3 对类中受保护方法的调用A通过,而其他 3 个测试(1,2,4)产生错误?

4

5 回答 5

2

这与子类无关。

您不能从静态函数调用非静态方法。现在

public static void main

是静态的,而

protectedMethod()

不是。

其次,您不能从类的“外部”调用受保护的方法。如果您在 B 类中,则不能调用不是 B 的另一个类的受保护方法。

最后,对于第 4 点,此代码不是方法的一部分,因此根本没有任何意义。

于 2010-11-23T05:14:28.667 回答
1

测试 1:这与受保护/私有/公共无关 - 您需要一个对象实例A来调用此方法。

测试 2:您不在 A 或 B 的对象实例中,而是在静态方法中。您需要从 A 或 B 中调用受保护的方法 - 在静态方法中不在类中,只有实例计数。

测试 3:你在实例中。

测试 4:与测试 2 相同 - 这是一个匿名静态方法。

于 2010-11-23T05:15:20.623 回答
1

与其说您在理解protected访问方面有困难,不如说是您在理解可以调​​用实例方法的地方有困难。

protectedMethod()是一种可以在class实例A上调用的方法。

第一个方法调用main()无效,因为您没有尝试在 - 的实例上调用该方法A-main()是静态方法,因此它属于 的B不是 的实例B

第四种是无效的,因为您不能将方法作为方法体之外的语句来调用。

于 2010-11-23T05:16:47.567 回答
0
  • 父类中的protected方法允许子类在内部使用它,这就是“测试 3”通过的原因。
  • 测试 1 失败,因为main它是一个静态方法并且无法访问非静态字段和函数。
  • 测试 2 失败,因为您尝试protected通过实例调用方法,这是不允许的。与测试 4 相同。
于 2010-11-23T05:15:15.397 回答
0

要了解您的问题,您首先需要了解访问修饰符:

  • Public:任何类都可以访问这个函数/变量。(您仍然必须先创建一个实例)
  • Private:没有其他类可以访问此函数/变量。它只能在类内部访问。您仍然可以使用该类中的公共函数来访问它的私有函数和变量,但无法直接访问。请注意,私有函数和变量不是继承的(即不是子类的一部分)。
  • 受保护的:受保护的函数和变量只能由该类及其任何子类(直接/间接继承自它的任何类)访问

静态:允许您调用函数而无需先创建对象。Math 类是一个很好的例子,因为它只包含静态方法和变量(甚至不能被实例化)。(注意:Static 不是访问修饰符。它的作用还不止于此,如果您想了解更多信息,请查阅)

至于你的例子:

  1. 测试 1:您的方法继承自 A 类,因此可用。但是,由于它不是静态方法,因此无法直接访问:您要么需要将其设为静态,要么创建 B 类的实例,然后通过该实例调用该函数。
  2. 测试 2:这不起作用,因为 A & B 在不同的包中。只允许在同一个包中访问受保护的方法(即使一个包继承自另一个包)。如果 A 和 B 在同一个包中,这将起作用。
  3. 测试 3:对象 B 继承了 A 的 public 和 protected 方法。访问的不是 A 中的方法,而是 B 中的继承方法。要看到这一点,请将 A 的代码更改为以下内容:

    <!-- language: java -->
    
    protected void protectedMethod() {
        System.out.println(getClass().getName() + ("'s Protected method"));
    }
    

    执行此操作将给出B's Protected method结果。

  4. 测试 4:在函数之外执行代码不起作用。不要这样做(永远)。

注意:您可以通过反射访问私有变量和受保护变量,尽管这是更高级的事情。这通常也不是一个好主意,因为变量被设为私有/受保护是有原因的(即防止未经授权的访问/修改)

于 2014-03-05T10:34:44.320 回答