简体   繁体   English

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

[英]Java - Help me Understanding Access to protected members from subclass (Again)

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. 好吧,我必须承认我是Java编程的新手,并且很犹豫在此处发布问题,因为有很多与我的问题相似的问题。 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 这是PackOne包中的A

package PackOne;

public class A {

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

}

Here is Class B in package PackTwo . 这是PackTwo包中的B类。 However, it is a subclass of class A . 但是,它是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? 请说明为什么只传递了Test 3对类A受保护方法的调用,而其他3个Tests(1,2,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. 如果您在B类中,则不能调用另一个非B类的受保护方法。

Finally, with point 4, this code is not part of a method, so it doesn't make any sense at all. 最后,对于第4点,此代码不是方法的一部分,因此根本没有任何意义。

Test 1: This is nothing to do with protected/private/public - you need an object instance of A to call this method. 测试1:这与受保护/私有/公共无关-您需要A的对象实例才能调用此方法。

Test 2: You are NOT in an object instance of A or B, you are in a static method. 测试2:您不在A或B的对象实例中,而是在静态方法中。 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. 您需要从A或B内调用受保护的方法-在静态方法中不在类之内,仅实例计数。

Test 3: You are in the instance. 测试3:您在实例中。

Test 4: Same as Test 2 - this is an anonymous static method. 测试4:与测试2相同-这是一个匿名的静态方法。

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. 这不仅仅意味着您不了解protected访问,还不了解您可以在何处调用实例方法。

protectedMethod() is a method you can call on instances of class A . protectedMethod()是可以在类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 . main()的第一个方法调用无效,因为您没有尝试在A实例上调用该方法main()是静态方法,因此它属于B 而不是B实例。

The fourth is not valid because you cannot call methods as statements outside of a method body. 第四个无效,因为您不能在方法主体外部将方法作为语句调用。

To understand your problem, you first need to understand the access modifiers: 要了解您的问题,您首先需要了解访问修饰符:

  • Public : Any class can access this function/variable. Public :任何类都可以访问此函数/变量。 (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 (ie 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). Math类是一个很好的示例,因为它仅包含静态方法和变量(甚至无法实例化)。 (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) (注意:Static不是访问修饰符。它不仅执行此操作,还需要执行其他操作,如果您想了解更多,请查询一下)

As for your example: 至于你的例子:

  1. Test 1 : Your method is inherited from class A, and thus available. 测试1 :您的方法是从类A继承的,因此可以使用。 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. 但是,由于它不是静态方法,因此无法直接访问它:您需要将其设置为静态,或者创建B类的实例,然后通过该实例调用该函数。
  2. Test 2 : This doesn't work because A & B are in different packages. 测试2 :这无效,因为A和B位于不同的包装中。 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. 如果A和B在同一包中,则可以使用。
  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: 测试3 :对象B继承了A的公共方法和受保护的方法。访问的不是A中的方法,而是B中的继承方法。要看到这一点,请将A的代码更改为以下代码:

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

    Executing this will give B's Protected method as a result. 执行此操作将得到B's Protected method

  4. Test 4 : Executing code outside of a function doesn't work. 测试4 :在函数外部执行代码不起作用。 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 (ie to prevent unauthorized access/modifications) 通常也不是一个好主意,因为出于某种原因将变量设置为私有/受保护(例如,防止未经授权的访问/修改)

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM