Java 从包外的子类访问受保护的变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20404977/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 01:43:19  来源:igfitidea点击:

Accessing a protected variable from a subclass outside package

java

提问by chaitanya89

I have gone through so many websites which explains about access specifiers in java such as java papers, java's access specifiers, and many other stackoverflow questions like here.

我浏览了很多解释java 中的访问说明符的网站,例如java 论文java 的访问说明符以及许多其他计算器溢出问题,例如这里

All these guys explained that the protected member can be accessed by any subclass(also by the subclass out of package) and can be accessed by the package level classes.

所有这些人都解释说,受保护的成员可以被任何子类(也可以被包外的子类)访问,并且可以被包级别的类访问。

While experimenting on protected members, I found out that I'm unable to access a protected member from a subclass outside package.

在对受保护成员进行试验时,我发现我无法从包外的子类访问受保护成员。

Check the code below. A public class with protected members:

检查下面的代码。具有受保护成员的公共类:

package com.One;

    public class ProVars {

    protected int i = 900;

    protected void foo()
    {
        System.out.println("foo");
    }

}

Another public class in different package trying to access protected member:

不同包中的另一个公共类试图访问受保护的成员:

package com.Two;

import com.One.ProVars;

public class AnotherClass extends ProVars {

    public static void main(String[] args) {
        ProVars p = new ProVars();
        System.out.println(p.i);//the field ProVars.i is not visible(Compilation Error)
                p.foo();//the method foo() from the type ProVars is not visible

    }
}

Any explanation is appreciated.

任何解释表示赞赏。

采纳答案by christopher

You're attempting to use them as if they were public. They are not public, they are protected.

您正试图像使用它们一样使用它们public。他们不是public,他们是protected

Example

例子

ProVars p = new ProVars();
p.foo(); // This will throw an error because foo() is not public.

The correct usage, for a subclass to use a protectedmethod or variable is:

子类使用protected方法或变量的正确用法是:

public class MyClass extends ProVars
{
     public MyClass()
     {
           System.out.println(i); // I can access it like this.
           foo(); // And this.
     }
}

Why does this work?

为什么这样做?

Because you've inheritedthe class. That means you've got all of its methods and it's variables. Now, because your method and variable is protected, it also means that it can be accessed from the subclass. Try and declare them as privateand see what happens.

因为你有inherited课。这意味着您已经获得了它的所有方法和变量。现在,因为您的方法和变量是protected,这也意味着可以从subclass. 尝试将它们声明为private,看看会发生什么。

回答by SLaks

Even inside a derived class, you can only access a protected field from a qualifier that is at least of your own type.

即使在派生类中,您也只能从至少属于您自己类型的限定符访问受保护的字段。

Inside AnotherClass, you can access new AnotherClass().i, but not new ProVars().i.

在里面AnotherClass,你可以访问new AnotherClass().i,但不能new ProVars().i

回答by jny

When we say it is available from subclass, we mean it is available to subclass code. But in your example you are calling protected method from outside.

当我们说它对子类可用时,我们的意思是它对子类代码可用。但是在您的示例中,您是从外部调用 protected 方法。

So while your example does not work, this should

因此,虽然您的示例不起作用,但这应该

package com.Two;

import com.One.ProVars;

public class AnotherClass extends ProVars {

public static void main(String[] args) {
    ProVars p = new ProVars();
    p.test();
}

public test() {
        System.out.println(this.i);)
        this.foo();
}



}

回答by david a.

Use the subclass In your main():

使用子类在您的main()

public class AnotherClass extends ProVars {

    public static void main(String[] args) {
    AnotherClass p = new AnotherClass();
    System.out.println(p.i);
            p.foo();

}

}

回答by Tim B

Your code accessing the variables is inside a static method - the static method is not directly part of an object that inherits the protected fields.

您访问变量的代码位于静态方法内 - 静态方法不是继承受保护字段的对象的直接一部分。

Try moving the code to a method inside your AnotherClass class and then calling that method from your static method.

尝试将代码移动到您的 AnotherClass 类中的一个方法,然后从您的静态方法中调用该方法。

回答by dimoniy

It would be fine if your main method wasn't static. Static methods don't care about inheritance hence your "extends ProVars" is not going to work. This on the other hand should work:

如果您的主要方法不是静态的,那就没问题了。静态方法不关心继承,因此您的“扩展 ProVars”将不起作用。另一方面,这应该有效:

public class AnotherClass extends ProVars {

   public void accessProtected() {
       System.out.println(this.i);
       this.foo();
    }

    public static void main(String[] args) {
        AnotherClass p = new AnotherClass();
        p.accessProtected();
    }

}

回答by Chang

You need to change the line ProVars p = new ProVars();into AnotherClass p = new AnotherClass();

您需要将行更改 ProVars p = new ProVars();AnotherClass p = new AnotherClass();

Otherwise, you're still creating an object of type ProVars, and the compiler won't be able to realise the inheritance between AnotherClass and ProVars (which leads to the compilation error).

否则,您仍然在创建 ProVars 类型的对象,编译器将无法实现 AnotherClass 和 ProVars 之间的继承(这会导致编译错误)。

回答by Utpal Kumar

Members declared protected in a class in one package is inherited by subclass which could lie either in same package of the class or in different package.

在一个包中的类中声明为 protected 的成员由子类继承,子类可以位于该类的同一包中,也可以位于不同的包中。

**Here inherited means same protected member of super class is available in subclass, use of parent reference and dot operator to access like below will throw compilation error.

**这里继承是指在子类中可以使用超类的相同受保护成员,使用父引用和点运算符访问如下将引发编译错误。

ProVars p = new ProVars();
System.out.println(p.i);// error: i has protected access in parent

simply use this in your subclass:

只需在您的子类中使用它:

System.out.println(i); // works fine, since subclass inherit the protected 
                          member of super class no matter whether they are in 
                          same or different package.

回答by yvolk

Confusion with Java protectedaccess is caused by the wrong tutorial: https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

与 Java保护访问的混淆是由错误的教程引起的:https: //docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

Reading the tutorial even several times doesn't give a clue, why you cannot access protected member of an object of class Alphafrom another objectof another package, whose class AlphaSubis a subclass of Alpha.

甚至多次阅读教程也没有提供线索,为什么您不能从另一个包的另一个对象访问Alpha类对象的受保护成员,其类AlphaSubAlpha的子类。

Actually, Java Language Specification explains this, e.g. in JLS 8:

实际上,Java 语言规范对此进行了解释,例如在 JLS 8 中:

6.6.2 Details on protected Access

6.6.2 受保护访问的详细信息

A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.

对象的受保护成员或构造函数可以从包的外部访问,在该包中仅由负责实现该对象的代码声明它。

回答by Li Jing

Two ConditionsMust Meet to access the protected field in the super class

必须满足两个条件才能访问超类中的受保护字段

1) protected and are accessible outside the package points only in subclasses of class

1) 受保护并且只能在类的子类中在包点之外访问

The second one is always be ignored that is

第二个总是被忽略

2) they are fields of objects that are being implemented by the code that is accessing them.

2) 它们是由访问它们的代码实现的对象字段。

please refer to this JavaDocs https://docs.oracle.com/javase/specs/jls/se11/html/jls-6.html#jls-6.6.2

请参阅此 JavaDocs https://docs.oracle.com/javase/specs/jls/se11/html/jls-6.html#jls-6.6.2