Java 具有包访问的抽象方法的继承
根据JLS第8.1.1.1节,我们有: 如果满足以下任一条件,则类C具有抽象方法: •C的任何成员方法(§8.2)——声明的或继承的——都是 抽象的 •C的任何超类都有一个用包访问声明的抽象方法, 并且不存在重写C或中的抽象方法的方法 C的超类Java 具有包访问的抽象方法的继承,java,inheritance,abstract,Java,Inheritance,Abstract,根据JLS第8.1.1.1节,我们有: 如果满足以下任一条件,则类C具有抽象方法: •C的任何成员方法(§8.2)——声明的或继承的——都是 抽象的 •C的任何超类都有一个用包访问声明的抽象方法, 并且不存在重写C或中的抽象方法的方法 C的超类 有趣的是,为什么我们有第二个选择呢。特别是,为什么我们有确切的“包访问”。那么“public”或“protected”方法呢?这可能意味着protected和public也是提供包访问的声明私有方法不是,它们也不能是抽象的。从最私有到最开放的顺序,jav
有趣的是,为什么我们有第二个选择呢。特别是,为什么我们有确切的“包访问”。那么“public”或“protected”方法呢?这可能意味着
protected
和public
也是提供包访问的声明<代码>私有方法不是,它们也不能是抽象的。从最私有到最开放的顺序,java修饰符是:
- 私人的
- 包装
- 保护
- 公开的
这是一个荒谬的情况,我永远不会期望在任何地方的任何节目中看到这一点。但是必须完全指定语言,否则可能会出现一个奇怪的错误,允许实例化具有未定义方法的类。是的,我认为你是对的。 第二种选择只涉及一种特殊情况: 特定的子类与其超类位于不同的包中 比如说,
package superpackage;
public abstract class SuperFoo {
abstract void foo();
}
package subpackage;
import superpackage.SuperFoo;
public abstract class SubFoo extends SuperFoo {}
package subclass;
import subpackage.SubFoo;
public class SecondSubFoo extends SubFoo {
@Override
void foo() {}
}
请注意,这个类应该声明为抽象类,否则我们就有编译错误
在这种特殊情况下,我们没有继承所需的“foo方法的继承”
该Subfo类必须与SuperFoo位于同一个包中。
有关更多详细信息,请参见JLS中的第8.4.8节
尽管如此,这个类仍然包含“foo”方法(根据定义),因此应该用abstract关键字标记
此外,我们可以通过属于“superpackage”包的另一个具体类来扩展Subfo类
比如说,
package superpackage;
public abstract class SuperFoo {
abstract void foo();
}
package subpackage;
import superpackage.SuperFoo;
public abstract class SubFoo extends SuperFoo {}
package subclass;
import subpackage.SubFoo;
public class SecondSubFoo extends SubFoo {
@Override
void foo() {}
}
注:
1) 事实上,公共和受保护的方法在继承时属于第一项定义,它们不需要第二项定义
2) 如果包访问方法在同一个包中,那么它们也属于第一个定义项,因此它们也不需要第二个定义项
3) 另一方面,另一个包中的包访问方法不属于定义的第一项,因为它们不是继承的(参见JSL第8.4.8节中抽象方法继承的定义)因此,它们是定义的第二项。基本上是说,在为所有抽象方法(类中显式的方法或父类中隐式的方法)提供具体实现之前,类是抽象的。记住:“包范围”是指您没有指定“public”或“protected”或“private”;它在包内的任何位置都可见,在包外不可见。