了解 Java 中抽象类的用途

2022-09-04 05:40:18

假设我有两个类,A和B。A类被定义为抽象类,而B扩展了这个抽象类,最后我测试结果,两个类都是同一包的一部分。

public abstract class A {

    protected abstract void method1(); 

    protected void method2() { 
        System.out.println("This is Class A's method"); 
    } 
}

public class B extends A {

    @Override
    protected void method1() {
        System.out.println("This is B's implementaiton of A's method");
    } 
}  

现在当我测试它们时:

B b = new B();
b.method1();
b.method2();  

我得到预期的输出:

This is B's implementaiton of A's method
This is Class A's method

问题:

  • 关键字的目的是什么,因为如果我省略它,它仍然工作相同。@Override
  • 如果我不实现抽象方法,我会收到编译错误。那么,这与实现接口有什么区别呢?
  • 另外,我也可以在B中实现。然后,输出将更改为 B 中的用法。这不也是重写父类方法吗?那么,在类 A 中显式定义一个抽象的方法的目的是什么呢?method2()

答案 1
  1. @Override不是关键字,它是一个可选的注释,可帮助编译器检查您是否确实正在重写某个方法。如果你说但没有方法可以覆盖,编译器会告诉你你可能犯了一个错别字。重命名为以查看效果。@Overridemethod1method12
  2. 接口不能有任何实现,而抽象类可以选择为其某些方法提供实现。此外,接口不能具有数据成员。
  3. 将方法定义为抽象意味着派生类必须提供实现。不将其声明为抽象表示派生类可以简单地提供自己的实现,但它们不需要。

答案 2

@Override

@Override是在Java 5中引入的(并在Java 6中进行了一点扩展)。它只是提供信息。它说“我假设重写父类或接口中已经存在的东西。

像Eclipse这样的IDE可以在没有这样的父方法的情况下警告你(例如,如果你拼错了名称)。在这种情况下,将不会调用您的方法(由于拼写错误)。

但不要太担心。

抽象类与接口

抽象类允许您定义基本功能,留下未定义的部分。接口不允许您实现任何内容。您可以对除每种情况下真正更改的部分以外的所有内容进行编程。因此,当您需要它时,您可以继承并实现缺少的部分。

重写两种方法

是的。在 Java 中,您可以重写父类中未显式声明为 final 的所有方法。没关系。如果你想让它不可修改,你可以宣布它是最终的。例如,如果要声明排序,可以:

public abstract class Ordering<X>
{
abstract boolean isLower(X a, X b);
abstract boolean isEquals(X a, X b);
   final boolean isGreater(X a, X b) {
      return !isLower(a, b) && !isEquals(a, b);
   }
}

当然,覆盖isGreater来实现它的另一种更有效的方法可能是有意义的(想象一下比较成本很高)。但是,在某些情况下,当您想要提供基本的已实现功能时(然后当抽象类比接口更好时),或者当您想要强制某些实现时(然后是当最终关键字显示有用时)。


推荐