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

Java 从子类访问受保护的超类成员,java,inheritance,protected,Java,Inheritance,Protected,我在读这本Java SCJP的书,我发现: 受保护的和默认的访问控制 水平几乎相同,但有一个关键区别。A. 只有当类访问默认成员时,才能访问该成员 属于同一个包,而受保护的成员可以是 由子类访问(通过继承),即使该子类是 在另一个包裹里 所以我决定测试受保护的点 我有一个包裹里的超级班级 package scjp; public class Token { protected int age = 6; //This is the protected class-level varia

我在读这本Java SCJP的书,我发现:

受保护的和默认的访问控制 水平几乎相同,但有一个关键区别。A. 只有当类访问默认成员时,才能访问该成员 属于同一个包,而受保护的成员可以是 由子类访问(通过继承),即使该子类是 在另一个包裹里

所以我决定测试
受保护的

我有一个包裹里的超级班级

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);
    }

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

但我得到了这个错误:

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

那么,出了什么问题了?

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

   System.out.println(new Token().age);
应该有用

另外,由于您的
子是一个令牌,您应该能够直接访问它,除非您的子类中有另一个同名的变量(阴影),在这种情况下,它将访问在子类中声明的“age”,因为我可以看到您没有在子类中声明
age
,您也可以这样直接访问它:

System.out.println(age);

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

   System.out.println(new Token().age);
应该有用

另外,由于您的
子是一个令牌,您应该能够直接访问它,除非您的子类中有另一个同名的变量(阴影),在这种情况下,它将访问在子类中声明的“age”,因为我可以看到您没有在子类中声明
age
,您也可以这样直接访问它:

System.out.println(age);

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

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

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

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

将编译并正常工作。

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

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

将编译并运行良好。

您误解了这个概念

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

意味着您可以通过在类中扩展成员来访问该成员,但您试图通过静态概念访问类中的变量,即使您的变量不是静态的 因此,我认为您必须了解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);
子类:

public class Token {
   protected static int age = 6; //This is the protected class-level variable.
  ....
}
  System.out.println(son.age);

你误解了这个概念

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

意味着您可以通过在类中扩展成员来访问该成员,但您试图通过静态概念访问类中的变量,即使您的变量不是静态的 因此,我认为您必须了解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);
子类:

public class Token {
   protected static int age = 6; //This is the protected class-level variable.
  ....
}
  System.out.println(son.age);

您不能访问静态成员,如果您想测试继承性,可以执行以下操作

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

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

您不能访问静态成员,如果您想测试继承性,可以执行以下操作

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

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

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

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

public class son extends Token{
   public void test1() {
     System.out.println(age); // 6
     System.out.println(new Token().age); // 6 This also works.
   }
}
您不能从子类访问它。您正在从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.
   }
}

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

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

public class son extends Token{
   public void test1() {
     System.out.println(age); // 6
     System.out.println(new Token().age); // 6 This also works.
   }
}
您不能从子类访问它。您正在从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.
   }
}

您需要在尝试访问类的非静态成员之前创建实例。您需要创建