【问题标题】:Protected member behavior once it was inherited.继承后受保护的成员行为。
【发布时间】:2012-10-03 10:20:24
【问题描述】:

我对受保护的标识符有一些疑问。在 K.Sierra 的 Sun Certified Java Programmer Study Guide 的第一章中,我发现了以下信息:

“一旦包外的子类继承了受保护的成员,该成员(由子类继承)就成为子类之外的任何代码的私有成员,子类的子类除外。”

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

// 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”变量的访问,这对我来说有点令人惊讶,因为它不符合声明“成为子类之外的任何代码的私有”

更改后的邻居类:

package package1;

import package2.Child;

public class Neighbour {

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

请向我澄清。谢谢。

【问题讨论】:

    标签: java inheritance protected scjp


    【解决方案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
        }
    }
    

    【讨论】:

      【解决方案2】:

      还有一个对“i”变量的访问,这对我来说有点令人惊讶,因为它不符合“对子类之外的任何代码变为私有”的声明

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

      “一旦包外的子类继承了受保护的成员,该成员(由子类继承)就成为子类之外的任何代码的私有成员,子类的子类除外。”

      --> 在包内,它仍然是受保护的,并且对于包内的所有类都不是私有的。

      【讨论】:

      • +1 - 用于解释为什么 OP 观察到的行为实际上与 K.Sierra 的书一致。
      【解决方案3】:

      简而言之,protected 是包私有的并且对子类可见。甚至 JLS 对此也含糊其辞 (JLS §6.6.2):

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

      它指定在包之外,只有子类可以访问受保护的成员。这暗示您也可以访问包中的变量。措辞不好,但受保护的成员具有包级别的可见性以及子类级别的可见性。

      另见:

      【讨论】:

        【解决方案4】:

        真相不在《Sun Certified Java Programmer Study Guide》中,而是在Java Language Specification中

        6.6.2。受保护访问的详细信息

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

        【讨论】:

        • 的确,SCJPSG 不是确定的。但是,这并不意味着它不正确。请参阅 Nandkumar Tekale 的回答。
        • “一旦包外的子类继承了受保护的成员,该成员(由子类继承)对子类之外的任何代码都是私有的” - 就个人而言,我认为它不正确且具有误导性.
        猜你喜欢
        • 2016-06-12
        • 2014-06-09
        • 2018-12-27
        • 2023-03-03
        • 2014-01-30
        • 1970-01-01
        • 2023-03-23
        • 2012-09-12
        • 2012-09-26
        相关资源
        最近更新 更多