繁体   English   中英

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

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

好吧,我必须承认我是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.
}

请说明为什么只传递了Test 3对类A受保护方法的调用,而其他3个Tests(1,2,4)却产生了错误?

这与子类无关。

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

public static void main

是静态的,而

protectedMethod()

不是。

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

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

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

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

测试3:您在实例中。

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

这不仅仅意味着您不了解protected访问,还不了解您可以在何处调用实例方法。

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

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

第四个无效,因为您不能在方法主体外部将方法作为语句调用。

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

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

静态 :允许您调用函数而不必先创建对象。 Math类是一个很好的示例,因为它仅包含静态方法和变量(甚至无法实例化)。 (注意:Static不是访问修饰符。它不仅执行此操作,还需要执行其他操作,如果您想了解更多,请查询一下)

至于你的例子:

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

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

    执行此操作将得到B's Protected method

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

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

  • 父类中的protected方法允许子类在内部使用它,这就是“测试3”通过的原因。
  • 测试1失败,因为main是静态方法,无法访问非静态字段和函数。
  • 测试2失败,因为您尝试通过实例调用protected方法,这是不允许的。 与测试4相同。

暂无
暂无

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

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