java中的受保护访问不起作用

时间:2014-01-18 07:48:22

标签: 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
    }
}

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

3 个答案:

答案 0 :(得分:3)

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

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

你做不到。这就是它通过错误告诉你的。

Section 6.6.1 of the JLS告诉我们:

  

引用的成员(类,接口,字段或方法)(类,   接口或数组)类型或类类型的构造函数是   只有当类型可访问且成员或者成员时才可访问   声明构造函数允许访问:

     
      
  • 如果成员或构造函数被声明为public,则访问权限为   允许的。接口的所有成员都是隐式公开的。

  •   
  • 否则,如果成员或构造函数被声明为protected,那么   只有在满足以下条件之一时才允许访问:

         
        
    • 在包中发生对成员或构造函数的访问   包含受保护成员或构造函数所在的类   声明。

    •   
    • 访问是正确的,如§6.6.2。

    • 中所述   
  •   

我们跳转到6.6.2.2并找到:

  

只有在定义它的包中,类实例创建表达式(不声明匿名类)才能访问受保护的构造函数。

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

您的data.Operations课程延长了access.test,自access.test宣布public以来就没问题了。您的构造函数是包私有的,因此您可以调用:

Operations o = new Operations("Operations!");
data.Operations.main()中的

Operation的构造函数调用super(s)允许它执行,因为它是一个子类(事实上,它必须由于超类中没有无效的构造函数)。请注意,与<{1}}直接调用构造函数不一样

如果你有这个:

new

尝试使用Operations(String s){ super(s); access.test t = new access.test(s); } 时会产生相同的错误;你不能这样做。

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

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

声明受保护的方法意味着protected包中的类和子类(无论包)都可以调用它。因此,以下内容在access

中完全有效
data.Operations.main()

如果您的Operations o = new Operations("Operations!"); o.test1("hi!"); 包含在main()包中的另一个类(或另一个包中且dataOperations构造函数),则无法执行此操作。

public

答案 1 :(得分:0)

Constructors不是继承。 用它

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

答案 2 :(得分:0)

子类只访问其父类的受保护成员(如果它涉及其父类的实现)。因此,如果父构造函数受到保护且它位于不同的包中,则无法在子类中实例化父对象。