从子类访问受保护的超类成员

时间:2012-12-13 07:17:15

标签: java inheritance protected

我正在阅读这本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

那么,出了什么问题?

6 个答案:

答案 0 :(得分:3)

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

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

将编译并正常工作。

答案 1 :(得分:2)

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

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

应该有效

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

System.out.println(age);

答案 2 :(得分:1)

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

答案 3 :(得分: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);

答案 4 :(得分:0)

如果要测试继承,则无法访问静态成员,如下所示

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

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

答案 5 :(得分:0)

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

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

您没有从子类访问它。您正在从main()访问它。" main" method不是任何一个类的成员,但是它试图直接访问成员变量。

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.
   }
}