简体   繁体   中英

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. 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?

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.

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.

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.

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 (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). (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 (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.
  • 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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