理解Java中抽象类的目的

911*_*boS 13 java abstract-class overriding

假设我有两个类,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");
    } 
}  
Run Code Online (Sandbox Code Playgroud)

现在当我测试它们时:

B b = new B();
b.method1();
b.method2();  
Run Code Online (Sandbox Code Playgroud)

我得到预期的输出:

This is B's implementaiton of A's method
This is Class A's method
Run Code Online (Sandbox Code Playgroud)

问题:

  • @Override关键字的目的是什么,因为如果省略它,它仍然可以正常工作.
  • 如果我没有实现抽象方法,我会收到编译错误.那么实现接口有什么不同呢?
  • 另外,我也可以method2()在B中实现.然后输出更改为B中使用的内容.这是否也会覆盖父类方法?那么在A类中将方法明确定义为抽象的目的是什么?

das*_*ght 18

  1. @Override它不是关键字,它是一个可选的注释,可帮助编译器检查您确实覆盖了一个方法.如果你说@Override但没有方法可以覆盖,编译器会告诉你,你可能已经输了一个错字.重命名method1method12查看效果.
  2. 接口不能有任何实现,而抽象类可以选择为其某些方法提供实现.此外,接口不能包含数据成员.
  3. 将方法定义为抽象意味着派生类必须提供实现.不声明它是抽象的说派生类只能提供自己的实现,但他们不需要.


hel*_*ios 13

@覆盖

@Override是在Java 5中引入的(并在Java 6中进行了一些扩展).它只是提供信息.它说"我想要覆盖父类或接口中已经存在的东西.

像Eclipse这样的IDE可以在没有这样的父方法的情况下警告你(例如,如果你错误地使用了这个名字).在这种情况下,您的方法将不会被调用(因为拼写错误).

但是不要太担心它.

抽象类vs接口

抽象类允许您定义保留未定义部分的基本功能.界面不允许您实现任何内容.您可以对除了每种情况下真正发生变化的部分之外的所有内容进 所以当你需要它时,你继承并实现了缺失的部分.

覆盖两种方法

是.在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);
   }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 非常感谢!无论如何,通过查看示例,您将习惯于抽象/接口等.Spring框架就是一个很好的例子.事实上,如果您了解设计模式:抽象类与模板方法非常接近,而接口与(在许多其他事物中)策略模式相关.模板通过继承扩展,而策略通过组合扩展.再次:Spring框架及其所有模板和组件是一个非常好的例子.你会发现时间. (2认同)