# Java 中抽象类和接口的区别

> 原文： [https://beginnersbook.com/2013/05/abstract-class-vs-interface-in-java/](https://beginnersbook.com/2013/05/abstract-class-vs-interface-in-java/)

在本文中，我们将通过示例讨论 Java 中抽象类和接口之间的**差异。我已经在 [OOPs 概念](https://beginnersbook.com/2013/04/oops-concepts/) 的单独教程中介绍了抽象类和接口，因此我建议您先阅读它们，然后再考虑差异。
1.  [java 中的抽象类](https://beginnersbook.com/2013/05/java-abstract-class-method/)
2.  Java 中的[接口](https://beginnersbook.com/2013/05/java-interface/)**

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

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

## Java 中的抽象类 vs 接口

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

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

输出：

```java
display3 method
```

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

```java
//first interface
interface Example1{
    public void display1();
}
//second interface
interface Example2 {
    public void display2();
}
//This interface is extending both the above interfaces
interface Example3 extends Example1,Example2{
}
class Example4 implements Example3{
    public void display1(){
        System.out.println("display2 method");
    }
    public void display2(){
        System.out.println("display3 method");
    }
}
class Demo{
    public static void main(String args[]){
        Example4 obj=new Example4();
        obj.display1();
    }
}
```

输出：

```java
display2 method
```

### 差异 2：抽象类可以由类或抽象类扩展（继承）

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

输出：

```java
Example4-display2 method
```

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

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

输出：

```java
display1 method
```

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

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

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

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

输出：

```java
display1 method
```

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

```java
abstract class Example1{
   public abstract void display1();
}

class Example2 extends 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();
   }
}
```

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

```java
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：抽象类可以有保护和公共抽象方法

```java
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();
   }
}
```

**接口只能有公共抽象方法**

```java
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：抽象类可以具有任何访问描述符的静态，最终或静态最终变量

```java
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();
   }
}
```

**接口只能有公共静态最终（常量）变量**

```java
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();
   }
}
```