抽象方法实现与抽象方法重写。这两个对抽象类的意义是否相同?

时间:2017-07-01 01:40:11

标签: java inheritance

我几乎参加了 Java SE 8 Programmer I 考试( 1Z0-808 )。我使用本学习指南:https://www.selikoff.net/java-oca-8-programmer-i-study-guide/。在回答第5章(班级设计)中的复习问题时,我在这个问题上失败了:

关于具体子类,以下哪项是正确的? (选择所有适用的选项)

  1. 具体的子类可以声明为abstract。
  2. 具体的子类必须实现所有继承的抽象方法。
  3. 具体的子类必须实现一个中定义的所有方法 继承的接口。
  4. 不能将具体子类标记为final。
  5. 抽象方法不能被具体的子类覆盖。
  6. 我的回答是2和5.但只有第2个是正确的。我选择了第5个答案,因为我认为你不能从抽象类中覆盖抽象方法,但是你可以实现它,就像从Java 8开始几乎就像抽象类一样。

    在谈论抽象类时,知道接口抽象方法是实现的,而不是重写:说#34;抽象方法可以被具体的子类覆盖"而不是"抽象方法可以由具体的子类实现"?

    如果我们注意第二个答案(这是正确的答案),他们使用了"实施"。

3 个答案:

答案 0 :(得分:3)

这就是the specification使用此术语的方式:

  

如果非abstract方法mC覆盖了类mA中的抽象方法C,则mC被称为实现<来自mA的/ em> C

     

在类mC中声明或继承的实例方法C覆盖<{1}}接口C中声明的另一个方法mI I 1}},如果满足以下所有条件:[...]

请注意,在引用覆盖接口方法时,它确实使用术语“覆盖”

更简单地说,如果方法覆盖抽象方法(来自抽象类或接口),则覆盖方法实现抽象方法。不过,它仍然被认为是一种覆盖。

abstract class A {
    abstract void m();
    void n() {}
}
class C extends A {
    // C.m() both overrides and implements A.m()
    @Override
    void m() {}
    // C.n() overrides A.n(), but does not implement it
    @Override
    void n() {}
}

答案 1 :(得分:0)

  
      
  1. 具体的子类可以声明为abstract。
  2.   

由于措辞这是错误的:具体的 calss不能是 abstract ,如果它是一个子类和抽象, 因此它是抽象子类。

  
      
  1. 具体的子类必须实现所有继承的抽象方法。
  2.   

这实际上是trick question。子类不来实现任何抽象方法,但是,如果没有,它也必须被声明为抽象类。就像问题1一样,这是措辞;如果它是 abstract ,那么从技术上讲它不是具体的子类,所以这个问题都是正确的。

  
      
  1. 具体的子类必须实现继承接口中定义的所有方法。
  2.   

这也是true。但是,如果子类继承自已实现接口的超类,则子类不必重新实现它们,在这种情况下它将为false。

  
      
  1. 不能将具体子类标记为final。
  2.   

这是假的;当然是can

  
      
  1. 抽象方法不能被具体的子类覆盖。
  2.   

这是另一个措辞问题。从技术上讲,你不是overriding抽象方法,而是实现它,所以这将是错误的。覆盖方法意味着您覆盖的方法在其父类中具有完全匹配(名称,返回类型,参数)。隐藏方法与覆盖它们相同,只是隐藏仅适用于静态方法和字段。因此,如果方法具有主体,并且您在子类中实现相同的方法,那么您将覆盖它。如果在子类中实现抽象方法,那么您只是实现它。如果在子类中实现静态方法,则将其隐藏。

这些问题措辞可怕,试图传达他们对抽象类,接口和遗传性的看法。虽然,鉴于开发是关注细节,也许更重要的是......

希望能帮助澄清一些事情。

答案 2 :(得分:0)

Java语言规范没有定义“具体类”的概念。它确实讨论了具体的方法,其中具体方法具有已定义的实现(与没有主体,只有类型签名的抽象方法相对)。 Java 8在接口中的默认方法在这里稍微混乱,但并非完全:即使方法具有默认实现,它仍然被认为是抽象的(如果没有提供其他实现,则默认实现简单地复制到实现类中)。

由于具体类的概念定义不明确,因此很难确定地对其作出任何陈述。通常,当人们谈论具体类时,他们只是指一个非抽象类,但我也看到(并且自己使用)表达式“具体类型”来引用泛型类型的特定实例。例如,List<T>是通用的,但List<String>可以被视为List<T>的具体对应物,即使List仍然是抽象类型(因为它是一个接口)。 / p>

此外,由于一个类可以有多个独立的抽象接口继承层次结构,它可以同时具体化为其中一些,而对另一些则是抽象的!

简短的回答:当面对由不了解主题的人设计的测试时,忽视哪个答案是“正确的”变得毫无意义。从规范中学习,因为它是对语言中正确内容的规范定义。