原文: https://beginnersbook.com/2013/05/abstract-class-vs-interface-in-java/

在本文中,我们将通过示例讨论 Java 中抽象类和接口之间的**差异。我已经在 OOPs 概念 的单独教程中介绍了抽象类和接口,因此我建议您先阅读它们,然后再考虑差异。

  1. java 中的抽象类
  2. Java 中的接口 | | 抽象类 | 接口** | | —- | —- | —- | | 1 | 抽象类一次只能扩展一个类或一个抽象类 | 接口一次可以扩展任意数量的接口 | | 2 | 抽象类可以扩展另一个具体(常规)类或抽象类 | 接口只能扩展另一个接口 | | 3 | 抽象类可以同时具有抽象和具体方法 | 接口只能有抽象方法 | | 4 | 在抽象类关键字中,abstract是将方法声明为抽象的必需项 | 在接口关键字中,abstract是可选的,用于将方法声明为抽象 | | 五 | 抽象类可以具有受保护和公共抽象方法 | 接口只能有公共抽象方法 | | 6 | 抽象类可以使用任何访问描述符具有静态,最终或静态最终变量 | 接口只能有public static final(常量)变量 |

以下示例解释了上述每个要点:

Java 中的抽象类 vs 接口

差异 No.1:抽象类一次只能扩展一个类或一个抽象类

  1. class Example1{
  2. public void display1(){
  3. System.out.println("display1 method");
  4. }
  5. }
  6. abstract class Example2{
  7. public void display2(){
  8. System.out.println("display2 method");
  9. }
  10. }
  11. abstract class Example3 extends Example1{
  12. abstract void display3();
  13. }
  14. class Example4 extends Example3{
  15. public void display3(){
  16. System.out.println("display3 method");
  17. }
  18. }
  19. class Demo{
  20. public static void main(String args[]){
  21. Example4 obj=new Example4();
  22. obj.display3();
  23. }
  24. }

输出:

  1. display3 method

接口可以一次扩展任意数量的接口

  1. //first interface
  2. interface Example1{
  3. public void display1();
  4. }
  5. //second interface
  6. interface Example2 {
  7. public void display2();
  8. }
  9. //This interface is extending both the above interfaces
  10. interface Example3 extends Example1,Example2{
  11. }
  12. class Example4 implements Example3{
  13. public void display1(){
  14. System.out.println("display2 method");
  15. }
  16. public void display2(){
  17. System.out.println("display3 method");
  18. }
  19. }
  20. class Demo{
  21. public static void main(String args[]){
  22. Example4 obj=new Example4();
  23. obj.display1();
  24. }
  25. }

输出:

  1. display2 method

差异 2:抽象类可以由类或抽象类扩展(继承)

  1. class Example1{
  2. public void display1(){
  3. System.out.println("display1 method");
  4. }
  5. }
  6. abstract class Example2{
  7. public void display2(){
  8. System.out.println("display2 method");
  9. }
  10. }
  11. abstract class Example3 extends Example2{
  12. abstract void display3();
  13. }
  14. class Example4 extends Example3{
  15. public void display2(){
  16. System.out.println("Example4-display2 method");
  17. }
  18. public void display3(){
  19. System.out.println("display3 method");
  20. }
  21. }
  22. class Demo{
  23. public static void main(String args[]){
  24. Example4 obj=new Example4();
  25. obj.display2();
  26. }
  27. }

输出:

  1. Example4-display2 method

接口只能通过接口扩展。类必须实现它们而不是扩展

  1. interface Example1{
  2. public void display1();
  3. }
  4. interface Example2 extends Example1{
  5. }
  6. class Example3 implements Example2{
  7. public void display1(){
  8. System.out.println("display1 method");
  9. }
  10. }
  11. class Demo{
  12. public static void main(String args[]){
  13. Example3 obj=new Example3();
  14. obj.display1();
  15. }
  16. }

输出:

  1. display1 method

差异 3:抽象类可以同时具有抽象和具体方法

  1. abstract class Example1 {
  2. abstract void display1();
  3. public void display2(){
  4. System.out.println("display2 method");
  5. }
  6. }
  7. class Example2 extends Example1{
  8. public void display1(){
  9. System.out.println("display1 method");
  10. }
  11. }
  12. class Demo{
  13. public static void main(String args[]){
  14. Example2 obj=new Example2();
  15. obj.display1();
  16. }
  17. }

接口只能有抽象方法,它们不能有具体方法

  1. interface Example1{
  2. public abstract void display1();
  3. }
  4. class Example2 implements Example1{
  5. public void display1(){
  6. System.out.println("display1 method");
  7. }
  8. }
  9. class Demo{
  10. public static void main(String args[]){
  11. Example2 obj=new Example2();
  12. obj.display1();
  13. }
  14. }

输出:

  1. display1 method

差异 No.4:在抽象类中,关键字abstract是将方法声明为抽象的必需项

  1. abstract class Example1{
  2. public abstract void display1();
  3. }
  4. class Example2 extends Example1{
  5. public void display1(){
  6. System.out.println("display1 method");
  7. }
  8. public void display2(){
  9. System.out.println("display2 method");
  10. }
  11. }
  12. class Demo{
  13. public static void main(String args[]){
  14. Example2 obj=new Example2();
  15. obj.display1();
  16. }
  17. }

在接口中,关键字abstract是可选的,用于将方法声明为抽象,因为默认情况下所有方法都是抽象的

interface Example1{
    public void display1();
}
class Example2 implements Example1{
    public void display1(){
        System.out.println("display1 method");
    }
    public void display2(){
        System.out.println("display2 method");
    } 
}
class Demo{
   public static void main(String args[]){
       Example2 obj=new Example2();
       obj.display1();
   }
}

差异 No.5:抽象类可以有保护和公共抽象方法

abstract class Example1{
   protected abstract void display1();
   public abstract void display2();
   public abstract void display3();
}
class Example2 extends Example1{
   public void display1(){
       System.out.println("display1 method");
   }
   public void display2(){
      System.out.println("display2 method");
   }
   public void display3(){
      System.out.println("display3 method");
   }
}
class Demo{
   public static void main(String args[]){
      Example2 obj=new Example2();
      obj.display1();
   }
}

接口只能有公共抽象方法

interface Example1{
   void display1();
}
class Example2 implements Example1{
   public void display1(){
      System.out.println("display1 method");
   }
   public void display2(){ 
      System.out.println("display2 method");
   }
}
class Demo{
   public static void main(String args[]){
       Example2 obj=new Example2();
       obj.display1();
   }
}

差异 No.6:抽象类可以具有任何访问描述符的静态,最终或静态最终变量

abstract class Example1{
   private int numOne=10;
   protected final int numTwo=20;
   public static final int numThree=500;
   public void display1(){
      System.out.println("Num1="+numOne);
   }
}
class Example2 extends Example1{
   public void display2(){
      System.out.println("Num2="+numTwo);
      System.out.println("Num2="+numThree);
   }
}
class Demo{
   public static void main(String args[]){
      Example2 obj=new Example2(); 
      obj.display1();
      obj.display2();
   }
}

接口只能有公共静态最终(常量)变量

interface Example1{
   int numOne=10;
}
class Example2 implements Example1{
   public void display1(){
      System.out.println("Num1="+numOne);
   }
}
class Demo{
   public static void main(String args[]){
      Example2 obj=new Example2();
      obj.display1();
   }
}