1

我正在阅读这本 Java SCJP 书,我遇到了这个:

受保护的和默认的访问控制级别几乎相同,但有一个关键区别。只有当访问该成员的类属于同一个包时,才能访问默认成员,而即使子类位于不同的包中,子类也可以(通过继承)访问受保护的成员。

所以我决定测试一下protected

我在一个包中有一个超类

package scjp;

public class Token {

    protected int age = 6; //This is the protected class-level variable.

    public Token(String name){
        this.name = name;
    }
    public Token(String name, int age){
        this.name = name;
        this.age = age;
    }

    public String getName(){
        return this.name;
    }

    public int getAge(){
        return this.age;
    }
}

我在另一个包中有一个子类;

package pack;

import scjp.Token;

public class son extends Token{

    public static void main(String[] args) {
       System.out.println(Token.age);
    }

}

如您所见,我正在尝试访问age超类中受保护的类级整数变量。

但我得到这个错误:

 age has protected access in scjp.Token
        at pack.son.main(son.java:11)
Java Result: 1

那么,怎么了?

4

6 回答 6

3

您正在尝试使用类引用访问超类的非静态受保护成员。

public static void main(String[] args) {
       Token t = new Token("somehting");
       System.out.println(t.age);
    }

将编译并正常工作。

于 2012-12-13T07:22:56.557 回答
2

age不是您班级中的静态变量Token。它是一个实例非静态成员,您可以使用类的实例访问实例非静态成员。

   System.out.println(new Token().age);

应该管用

而且你Son IS-A Token 也应该能够直接访问它,除非你的 Son 类中有另一个具有相同名称(阴影)的变量,在这种情况下,它将访问 Son 中声明的“年龄”,我可以看到你没有声明age在您的 Son 类中,您也可以像这样直接访问它:

System.out.println(age);
于 2012-12-13T07:18:36.160 回答
1

age不是静态成员。您将需要使用类的实例来访问它Token。不是类名本身。

于 2012-12-13T07:19:09.150 回答
1

你误解了这个概念

而子类可以(通过继承)访问受保护的成员,即使该子类位于不同的包中。

意味着您可以通过在您的类中扩展它来访问该成员,但是您尝试通过静态概念访问您的类中的变量,即使您的变量不是静态的所以我认为您必须看一下 java 的基础知识。意味着您可以通过两种方式修复程序。

1. 创建您的类的对象并访问您的受保护变量,您必须创建一个应该调用父构造函数的构造函数。您的儿子班可能如下所示。

public son(String name) {
    super(name);
    // TODO Auto-generated constructor stub
}

public static void main(String[] args) {
    son s = new son("Hello"); //$NON-NLS-1$
   System.out.println(s.age);
}

2. 您可以通过将受保护的变量设为静态并从您的类中使用它来获得访问权限,如下所示。
令牌类:

public class Token {
   protected static int age = 6; //This is the protected class-level variable.
  ....
}

儿子班:

  System.out.println(son.age);
于 2012-12-13T07:23:24.597 回答
0

您无法访问静态成员,如果要测试继承,可以执行以下操作

public static void main(String[] args) {
   son s = new son();
   System.out.println(s.age);
}

您不应该使用以小写字母开头的公共类名称。

于 2013-07-01T02:40:57.177 回答
0

受保护成员:换句话说,受保护 = 继承

对于包外的子类,受保护的成员只能通过继承来访问。子类不能在超类引用上使用点运算符来访问受保护的成员。

您没有从子类访问它。您正在从 main() 访问它。“main”方法不是任一类的成员,但它试图直接访问成员变量。

public class son extends Token{
    public static void main(String[] args) {
       System.out.println(Token.age); // Error
    }
}

创建非静态方法并继承受保护的成员。

public class son extends Token{
   public void test1() {
     System.out.println(age); // 6
     System.out.println(new Token().age); // 6 This also works.
   }
}
于 2015-01-26T08:51:59.093 回答