如果 Base 和 Derived 类位于不同的包中,则来自Base的 package-private 成员不应被继承,因此它不应在Derived中不存在,即此类成员将无法通过并且-在任何一种情况下都会产生编译错误!Base obj = new Derived()
Derived obj = new Derived()
obj.member()
但我看到Base obj = new Derived()
,obj.f()
是可访问的!
是的,私有成员仍然存在,因为当我创建new Derived()
then时new Base()
,它的所有私有成员也被创建(在引擎盖下)。但是,如果我将下面代码中的 package-private 更改为private ,则会 出现编译错误(隐式存在的)其超类(基类)的私有 (-) 成员。f()
obj.f()
Base obj = new Derived()
(-)(因为 Base 和 Derived 在不同的包中)
package com.main_pkg;
public class Base {
void f() { } // default visibility
}
和
package org.another_pkg;
import com.main_pkg.Base;
public class Derived extends Base {
}
和
package com.totally.different_pkg;
import org.another_pkg.Derived;
public class DerivedFromDerived extends Derived {
}
最后
import org.another_pkg.Derived;
import com.totally.different_pkg.DerivedFromDerived;
public class Driver { // Base class is in same pkg as Driver!
public static void main(String[] args) {
Base obj1 = new Derived();
obj1.f(); // f() is visible!
Base obj2 = new DerivedFromDerived();
obj2.f(); // f() is visible!
}
}
您能否制定一个快速简便的实用规则(换句话说,不是在 JLS 和常见的默认可见性定义中)如何理解复杂继承/包组合中的可见性(访问)(我们可能有复杂的层次结构 Base-> Derived->Derived2->Derived3 并且每个类都可以在相同/不同的包中。如何快速查询可访问性?
例如,对于(基类的)受保护成员,“快速猜测”规则非常简单:
- 如果Base 和 Driver 在同一个包中(即来自代码
Base obj = new Base(); obj.baseProtectedMember();
编译的任何 Driver 的方法)=> 任何组合都可以工作(Base obj1 = new Derived2(); Derived2 obj2 = new Derived2() 等 -obj1.baseProtectedMember()
并且obj2.baseProtectedMember()
是可见的并且可以是称为)。而且我们不在乎其他类在什么包中! - 如果 Base 和 Driver 不在同一个包中(即来自任何 Driver 的方法,代码
Base obj = new Base(); obj.baseProtectedMember();
不会编译)=> 任何组合(参见 1)都不起作用。而且我们不在乎其他类在什么包中!
但是对于包私有成员,我们确实关心哪个层次类在哪个包中,我无法为一般情况制定一个简单可靠的“快速猜测”规则......
PS有趣的旁注:
如果我在上面的代码片段(帖子顶部)中覆盖 Derived 和 DerivedFromDerived 中的方法(将它们保留为包私有),则输出为:
f() from Base called
f() from Base called