Java - 帮助我理解从子类访问受保护的成员(再次)

发布于 2024-10-03 17:41:35 字数 1200 浏览 14 评论 0原文

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

这是包 PackOne 中的类 A

package PackOne;

public class A {

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

}

这是包 PackTwo 中的类 B。然而,它是类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)产生错误?

Well, I must admit that I'm very new to Java Programming and very hesitate to post the question here because there are lots of question similar to my question. I have viewed those question but STILL I can't understand what's the logic behind "protected" modifier. So I think it is better to post my own question here.

Here is class A in package PackOne

package PackOne;

public class A {

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

}

Here is Class B in package PackTwo. However, it is a subclass of 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.
}

Please explain Why only Test 3's call to protected method in class A is passed but the other 3 Tests(1,2,4) yield errors?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

笑忘罢 2024-10-10 17:41:35

这与子类无关。

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

public static void main

是静态的,而

protectedMethod()

不是。

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

。最后,根据第4点,这段代码不是方法的一部分,所以它根本没有任何意义。

This has nothing to do with subclasses.

You cannot call a non-static method from a static function. Now

public static void main

is static, while

protectedMethod()

is not.

Second, you cannot call protected methods from "outside" a class. If you are in class B, you cannot call a protected method of another class that isn't B.

Finally, with point 4, this code is not part of a method, so it doesn't make any sense at all.

熊抱啵儿 2024-10-10 17:41:35

测试 1:这与 protected/private/public 无关 - 您需要一个 A 的对象实例来调用此方法。

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

测试 3:您处于实例中。

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

Test 1: This is nothing to do with protected/private/public - you need an object instance of A to call this method.

Test 2: You are NOT in an object instance of A or B, you are in a static method. You need to be calling the protected method from within A or B - being in a static method is not within the class, only instances count.

Test 3: You are in the instance.

Test 4: Same as Test 2 - this is an anonymous static method.

十雾 2024-10-10 17:41:35

与其说您无法理解受保护访问,不如说您无法理解在哪里可以调用实例方法。

protectedMethod() 是您可以在类 A实例上调用的方法。

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

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

It's not so much that you're having trouble understanding protected access as you are having trouble understanding where you can call instance methods.

protectedMethod() is a method you can call on instances of class A.

The first method call in main() is invalid because you aren't attempting to call the method on an instance of A - main() is a static method and thus it belongs to the class of B rather than an instance of B.

The fourth is not valid because you cannot call methods as statements outside of a method body.

唯憾梦倾城 2024-10-10 17:41:35
  • 父类中受保护的方法允许子类在内部使用它,这就是“测试 3”通过的原因。
  • 测试 1 失败,因为 main 是静态方法,无法访问非静态字段和函数。
  • 测试 2 失败,因为您尝试通过实例调用受保护的方法,这是不允许的。与测试 4 相同。
  • A protected method in a parent class allows a subclass to use it internally, which is why 'Test 3' passes.
  • Test 1 fails because main is a static method and has no access to non-static fields and functions.
  • Test 2 fails because you are trying invoke a protected method via an instance, which is not allowed. Same with Test 4.
南冥有猫 2024-10-10 17:41:35

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

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

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

至于您的示例:

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

    
    
    受保护无效受保护方法(){
        System.out.println(getClass().getName() + ("受保护的方法"));
    }
    

    执行此命令将得到B 的受保护方法 结果。

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

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

To understand your problem, you first need to understand the access modifiers:

  • Public: Any class can access this function/variable. (You still have to create an instance first)
  • Private: No other class can access this function/variable. It can only be accessed inside the class. You can still use public functions from that class to access it's private functions and variables, but direct access is not possible. Note that private functions and variables are NOT inherited (i.e. not part of the subclass).
  • Protected: Protected functions and variables can only be accessed by that class and any of it's subclasses (any class that directly/indirectly inherits from it)

Static: allows you to call functions without having to create an object first. The Math class is a good example as it only contains static methods and variables (and can't even be instantiated). (note: Static is not an access modifier. It also does a bit more than just this, look it up if you want to know more)

As for your example:

  1. Test 1: Your method is inherited from class A, and thus available. However, since it is not a static method, it cannot be directly accessed: You either need to make it static, or create an instance of class B, then call the function through that instance.
  2. Test 2: This doesn't work because A & B are in different packages. Access to protected methods is only allowed within the same package (even if one inherits from the other). If A and B where in the same package, this would work.
  3. Test 3: Object B inherits public and protected methods of A. It's not the method in A that is accessed, but the inherited method in B. To see this, change A's code to the following:

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

    Executing this will give B's Protected method as a result.

  4. Test 4: Executing code outside of a function doesn't work. Don't do this (ever).

Note: You can access private and protected variables through reflection, though this is a far more advanced thing. It's usually also not a very idea, since variables are made private/protected for a reason (i.e. to prevent unauthorized access/modifications)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文