【问题标题】:Inheritance of abstract methods with package access使用包访问继承抽象方法
【发布时间】:2015-08-10 22:24:03
【问题描述】:

根据 JLS 的“8.1.1.1”部分,我们有:

如果满足以下任一条件,则 C 类具有抽象方法:

• C 的任何成员方法(第 8.2 节)——无论是声明的还是继承的——都是 摘要。

• C 的任何超类都有一个通过包访问声明的抽象方法, 并且不存在覆盖来自 C 或来自的抽象方法的方法 C的超类

有趣的是,为什么我们在这里有第二个选项。特别是,为什么我们有确切的“包访问权限”。那么“公共”或“受保护”方法呢?

【问题讨论】:

  • 这基本上是说你的类是抽象的,直到你为你的所有抽象方法提供具体的实现(你的类中显式的方法,或者来自父类的隐式方法)。请记住:“包范围”是指您指定“公共”或“受保护”或“私有”;它在包内的任何地方都可见,而在包外不可见。

标签: java inheritance abstract


【解决方案1】:

从最私密到最开放的顺序,java 修饰符 go:

  • 私人
  • 受保护
  • 公开

子类不能继承另一个包中父类的包方法。因此,根据规则 1,从这样的父类继承的类不会是抽象的。因此,存在第二条规则是为了解决子类从抽象父类继承而无法提供抽象包方法的实现的情况。

这是一种荒谬的情况,我永远不会期望在任何地方的任何程序中看到这种情况。但是必须完全指定语言,否则您最终可能会遇到一个奇怪的错误,该错误允许实例化具有未定义方法的类。

【讨论】:

    【解决方案2】:

    这可能的含义是protectedpublic 也是提供包访问的声明。 private 方法不是,也不能是抽象的。

    【讨论】:

      【解决方案3】:

      是的,我认为你是对的。 第二种选择仅涉及一种特殊情况: 特定的子类与其超类位于不同的包中。

      例如,

      package superpackage;
      
      public abstract class SuperFoo {
          abstract void foo();
      }
      
      
      package subpackage;
      
      import superpackage.SuperFoo;
      
      public abstract class SubFoo extends SuperFoo {}
      

      请注意,这个类应该声明为抽象类,否则会出现编译错误。

      在这种特殊情况下,我们没有“继承 foo 方法”,因为继承需要 该 SubFoo 类与 SuperFoo 在同一个包中。 有关详细信息,请参阅 JLS 中的第 8.4.8 节。

      尽管如此,这个类仍然包含“foo”方法(根据定义),因此应该用 abstract 关键字标记。

      此外,我们可以通过属于“超级包”包的另一个具体类来扩展我们的 SubFoo 类。

      例如,

      package subclass;
      
      import subpackage.SubFoo;
      
      public class SecondSubFoo extends SubFoo {
          @Override
          void foo() {}
      }
      

      注意:

      1) 事实上,公共和受保护的方法属于第一项定义,因为它们是继承的,不需要第二项定义。

      2) 如果包访问方法在同一个包中,它们也属于第一项定义,因此它们也不需要第二项定义。

      3) 另一方面,另一个包中的包访问方法不属于定义的第一项,因为它们不是继承的(参见 JSL 的第 8.4.8 节中抽象方法继承的定义)和因此它们是第二个定义项。

      【讨论】:

        猜你喜欢
        • 2015-02-09
        • 1970-01-01
        • 1970-01-01
        • 2012-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-01
        • 2012-08-06
        相关资源
        最近更新 更多