java - java 中的 protected 访问不起作用

标签 java inheritance public protected

考虑类测试

package access;

public class test {
    public String s;
    protected test(String s){
        this.s = s;
        System.out.println("access.test constructor");
    }

    protected void test1(String s){
        this.s = s;
        System.out.println("access.test test1 method");
    }
}

考虑类操作

package data;
public class Operations extends access.test{

    Operations(String s){
        super(s);
    }

    public static void main(String args []) {
        // TODO Auto-generated method stub

        //Operations O = new Operations("Operations!");
        access.test t = new access.test("hello");//1
        t.test1("hi!");                          //2
    }
}

构造函数 test 和方法 test1 在第 1 行和第 2 行不可见。为什么?

最佳答案

在您的data.Operations.main()中,您尝试通过new实例化access.test:

access.test t = new access.test("hello");//1

你不能这么做。这就是它通过错误告诉您的内容。

Section 6.6.1 of the JLS告诉我们:

A member (class, interface, field, or method) of a reference (class, interface, or array) type or a constructor of a class type is accessible only if the type is accessible and the member or constructor is declared to permit access:

  • If the member or constructor is declared public, then access is permitted. All members of interfaces are implicitly public.

  • Otherwise, if the member or constructor is declared protected, then access is permitted only when one of the following is true:

    • Access to the member or constructor occurs from within the package containing the class in which the protected member or constructor is declared.

    • Access is correct as described in §6.6.2.

我们跳转到6.6.2.2并找到:

A protected constructor can be accessed by a class instance creation expression (that does not declare an anonymous class) only from within the package in which it is defined.

access.test 位于不同的包中,并且您声明了构造函数 protected。只有 access 中的类可以直接调用构造函数(例如使用 new - 这就是“类实例创建表达式”的含义)。

您的data.Operations类扩展了access.test,这很好,因为access.test被声明为public >。您的构造函数是包私有(private)的,因此您可以调用:

Operations o = new Operations("Operations!");

data.Operations.main()中。 Operation 的构造函数调用 super(s) ,这是允许的,因为它是子类(事实上,它必须这样做,因为父类(super class)中没有空构造函数)。请注意,这与通过 new 直接调用构造函数不同

如果你有这个:

Operations(String s){
    super(s);
    access.test t = new access.test(s);
}

尝试使用new时会产生相同的错误;你不能那样做。

protected 方法与 protected 构造函数具有不同的访问规则。

您已将 access.test 中的 test1() 声明为 protected

将方法声明为 protected 意味着 access 包中的类和子类(无论包如何)都可以调用它。因此,以下内容在 data.Operations.main() 中完全有效:

Operations o = new Operations("Operations!");
o.test1("hi!");

如果您的 main() 位于 data 包中的不同类中(或在另一个包中,并且 Operations 有一个 public 构造函数),你不能这样做。

package data;

public class ThirdClass {

    public static void main(String[] args) {

        // This is perfectly fine since Operations has a package-private constructor
        Operations o = new Operations("Some String");
        // This won't compile
        o.test1("hi!");
    }

}

关于java - java 中的 protected 访问不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21201520/

相关文章:

java - 在面向服务的架构中何时使用 Web api 而不是依赖注入(inject)

c# - 一个列表中的多个结构类型

c# - 使用派生类的实例时如何序列化基类?

java - 使用公共(public)构造函数在java中创建一个单例类

c++ - 有没有办法访问同一类模板的不同实例化的私有(private)部分?

java - 多类 Java Applet

java - Java中是否有可以容纳4个或更多值的数据结构

java - next() 已耗尽元素时的并发修改

java - 如何扩展一个 java 类来扩展 Scala 中另一个类的类型参数?

java - 带有继承的Java程序应该如何追溯?