首页 文章

受保护的成员行为一旦被继承 .

提问于
浏览
6

我对保护标识符有一些疑问 . 在K.Sierra的Sun认证Java程序员学习指南的第一章中,我发现了以下信息:

"Once the subclass-outside-the-package inherits the protected member, that member (as inherited by the subclass) becomes private to any code outside the subclass, with the exception of subclasses of the subclass."

我提供了反映上述陈述的示例代码,对我来说绝对清楚 .

// Parent class
package package1;

import package2.Child;
public class Parent {

    protected int i = 5;

}

// Child class
package package2;

import package1.Parent;

public class Child extends Parent {

    // variable 'i' inherited

}


package package2;

public class Neighbour {

    public void protectedTesting(){
        Child child = new Child();
        System.out.println(child.i); // no access
    }
}

我已经开始尝试并进行了一些小改动 - 将Neighbor移到package1 . 并且可以访问"i"变量,这对我来说有点令人惊讶,因为它不符合声明 "becomes private to any code outside the subclass"

更改后的邻居类:

package package1;

import package2.Child;

public class Neighbour {

    public void protectedTesting(){
        Child child = new Child();
        System.out.println(child.i); // access!
    }
}

请向我澄清一下 . 谢谢 .

4 回答

  • 5

    简而言之, protected 是包私有的,也是子类可见的 . 甚至JLS对此也很模糊(JLS §6.6.2):

    对象的受保护成员或构造函数可以从包外部访问,只能通过负责实现该对象的代码来声明它 .

    它指定在包外部,只有子类可以访问受保护的成员 . 这意味着您还可以访问包中的变量 . 它的措辞很差,但真正的是受保护的成员具有包级别可见性以及子类级别的可见性 .

    也可以看看:

  • 3

    并且可以访问“i”变量,这对我来说有点令人惊讶,因为它不符合语句“对子类之外的任何代码变得私有”

    • 但你在 package1 包中移动了类 Neighbour ,根据 "Protected members can be accessed by classes in same package" 这是真的

    “一旦子类 - 包外继承受保护的成员,该成员(由子类继承)对子类外的任何代码都是私有的,但子类的子类除外 . ”

    • 在包内,它仍然受到保护,对包中的所有类都不是私有的 .

  • 1

    真相不在"Sun Certified Java Programmer Study Guide"但在Java Language Specification

    6.6.2 . 受保护访问的详细信息受保护的成员或对象的构造函数可以从包外部访问,只能通过负责实现该对象的代码来声明它 .

  • 1

    protected 可见性包括包级别可见性 . 继承允许您将 Child 对象视为 Parent 的实例 . 由于 Parent 的成员 i 在同一个包中声明,因此可以从 Neighbour 访问它 .

    package package1;
    
    import package2.Child;
    
    public class Neighbour {
    
        public void protectedTesting() {
            Parent neighboured = new Child();
            System.out.println(neighboured.i); // access
        }
    }
    

相关问题