【问题标题】:Access protected super-class member from sub-class从子类访问受保护的超类成员
【发布时间】:2012-12-01 01:10:50
【问题描述】:

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

那么,怎么了?

【问题讨论】:

  • 您需要先创建实例,然后再尝试访问类的非静态成员。

标签: java inheritance protected


【解决方案1】:

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

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

将编译并正常工作。

【讨论】:

    【解决方案2】:

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

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

    应该工作

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

    System.out.println(age);
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        你误解了这个概念

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

        意味着您可以通过在类中扩展成员来访问该成员,但是您尝试通过静态概念访问类中的变量,即使您的变量不是静态的 所以我认为你必须看看基本的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);
        

        【讨论】:

        • summit,但是在他的情况下,他并不需要创建一个实例。他可以直接作为 Son IS A Token 访问它:)
        • 嗨@GanGnaMStYleOverFlowErroR 是的,我更新了也可能实际上我正在写答案。一次写不出漏洞答案。 ;)
        【解决方案5】:

        你不能访问静态成员,如果你想测试继承,你可以这样做

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

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

        【讨论】:

          【解决方案6】:

          Protected Member : 换句话说,protected = Inheritance

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

          您没有从子类访问它。您正在从 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.
             }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-06-07
            • 2010-09-16
            • 2013-10-16
            • 2017-08-01
            • 2016-10-01
            • 2013-06-08
            • 1970-01-01
            相关资源
            最近更新 更多