接口和抽象类区别

抽象类和接口都是 Java 中的重要概念,它们在面向对象编程中都扮演着重要角色,但是它们之间有许多不同点。下面在概念、用法、特性、设计等方面详细比较抽象类和接口的区别。

这里先列举接口和抽象类的区别

  1. 抽象类可以有构造方法,而接口不能有构造方法。因为接口是抽象的,它没有实现,所以它没有构造方法。
  2. 抽象类可以有成员变量,而接口没有成员变量。因为接口中的所有变量都默认为public static final,所以它们必须被初始化,而且不能被修改。
  3. 抽象类可以有非抽象方法,而接口不能有非抽象方法。因为接口是抽象的,它只能有抽象方法,而抽象类可以有抽象方法和非抽象方法。
  4. 抽象类可以实现接口,而接口不能实现抽象类。因为接口是抽象的,它只能被实现,而抽象类可以被继承和实现。
  5. 抽象类的子类只能继承一个抽象类,而一个类可以实现多个接口。因为Java不支持多继承,所以一个类只能继承一个抽象类,但它可以实现多个接口。
  6. 抽象类可以有普通的方法,而接口不能有普通的方法。因为接口中的所有方法都默认为public abstract,所以它们不能有方法体,而抽象类可以有普通的方法和方法体。
  7. 抽象类的访问权限可以是public、protected和default,而接口的访问权限只能是public。因为接口是用来定义公共的API,所以它的访问权限只能是public,而抽象类可以有不同的访问权限。

概念

抽象类和接口都是 Java 中的概念。抽象类是一个已经存在的类,并且是一个被声明为抽象的类。接口是一种完全抽象的类,它只定义了一组方法的签名,并没有实现任何具体行为。

用法

抽象类和接口的用法也不同。对于抽象类来说,我们可以使用 abstract 关键字将某个类定义为抽象类,然后定义抽象方法,子类必须实现这个抽象方法或将子类也定义为抽象类。而对于接口来说,我们使用 interface 关键字来定义接口,接口中所有的方法都是抽象方法,而且默认已经加上 public abstract 修饰符,子类必须实现接口中的所有方法。

// 抽象类
public abstract class AbstractClass {

  public abstract void call();

}

// 接口
public interface MyInterface {

  void run();

}

特性

抽象类和接口也有自己独特的特性。抽象类不仅可以定义抽象方法,还可以定义普通方法、成员变量以及构造方法等。而接口则只能定义抽象方法、常量(final)和静态方法(JDK 1.8 后)。

此外,接口还具有多继承的特性。在 Java 中,一个类只能继承自一个父类(除了 Object 类),但是一个类可以实现多个接口。

// 抽象类
public abstract class AbstractClass {

  private int value;

  public AbstractClass(int value) {
    this.value = value;
  }

  public void say() {
    System.out.println("Hello!");
  }

}

// 接口
public interface MyInterface1 {

  void say();

}

public interface MyInterface2 {

  void run();

}

class MyClass implements MyInterface1, MyInterface2 {

  @Override
  public void say() {
    System.out.println("Hello");
  }

  @Override
  public void run() {
    System.out.println("run");
  }
}

设计

抽象类和接口的设计目的也不同。抽象类主要是为了让子类继承并实现一些通用的行为,比如 java.util.AbstractListjava.util.AbstractMap 等。而接口主要是为了定义一些行为规范,比如 java.util.Collectionjava.io.Serializable 等。

因此,在设计接口和抽象类时需要考虑到其用途和目的。如果要定义一些通用行为并在子类中实现,可以使用抽象类;如果要定义一些行为规范,并且希望多个类实现这些规范,可以使用接口。

JDK1.8接口特性

在 JDK 1.8 中,Java 语言引入了一种新的概念:默认方法(default method),也叫扩展方法。接口中可以定义默认方法和静态方法,这样子类就可以直接继承这些方法,避免了它们需要重新实现。

示例代码如下:

public interface MyInterface {

  void say();

  default void run() {
    System.out.println("run");
  }

  static void call() {
    System.out.println("call");
  }
}

// 如果想使用该接口的默认方法或静态方法,可以直接继承该接口即可
class MyClass implements MyInterface {

  @Override
  public void say() {
    System.out.println("say");
  }
}

JDK1.9接口特性

在 JDK 1.9 及后续的版本中,Java 语言对接口进行了一些改变,包括私有方法和私有静态方法。私有方法和私有静态方法只能在接口内部被调用,无法从接口的实现类或外部访问。

示例代码如下:

public interface MyInterface {

  void say();

  default void methodA() {
    methodB();
    methodC();
    System.out.println("methodA is running");
  }

  private void methodB() {
    System.out.println("methodB is running");
  }

  private static void methodC() {
    System.out.println("methodC is running");
  }
}

class MyClass implements MyInterface {

  @Override
  public void say() {
    System.out.println("say");
  }
}

这样,我们就可以在接口中定义一些私有方法或私有静态方法,可以更好地封装一些不希望被外部访问的逻辑。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值