考虑类测试
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
你不能这么做。这就是它通过错误告诉您的内容。
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/