java 抽象接口类_Java中的抽象类和接口的区别

本文主要列举Java语言中抽象类和接口的区别,不详细讲解接口和抽象类。

2b775e48ae3dbd2ebba14847e95fdf91.png

抽象类和接口.png

不知道大家有没有注意到,凡是问到某两个事物的区别,都会首先介绍它们的共同点,然后再介绍它们的区别,我们这里也不例外:

1、相同点

1.1. 接口和抽象类都不能被实例化

public interface Flyable { // 声明接口

}

public abstract class Flyer { // 声明抽象类

}

public class InstantiateTest {

public static void main( String[] args ){

Flyable a = new Flyable(); // 编译错误

Flyer b = new Flyer() ; // 编译错误

}

}

1.2. 接口和抽象类中都可以包含抽象方法

public interface Flyable {

public abstract void fly() ; // 默认都是 public abstract 所修饰

}

public abstract class Flyer {

public abstract void fly() ; // 必须显式指定 abstract 修饰符

}

1.3. 接口和抽象类中都可以包含非抽象的实例方法 ( 从Java 8 开始 )

public interface Flyable {

// 从 Java 8 开始可以在接口中声明 default 修饰的、非抽象的实例方法

public default void initialize() {

}

}

public abstract class Flyer {

// Java 类中本类就可以声明非抽象实例方法

public void initialize() {

}

}

1.4. 接口和抽象类中都可以包含类方法 ( 从Java 8 开始 )

public interface Flyable {

// 从 Java 8 开始可以在接口中声明类方法

public static void prepare() {

}

}

public abstract class Flyer {

// Java 类中本类就可以声明类方法

public static void prepare() {

}

}

1.5. 接口和抽象类中都可以包含私有方法 ( 从Java 9 开始 )

public interface Flyable {

// 从 Java 9 开始可以在接口中声明 private 修饰的非抽象方法

private void ready() {

}

private static void hello(){

}

}

public abstract class Flyer {

// Java 类中本类就可以声明私有方法

private void ready() {

}

private static void hello(){

}

}

1.6. 接口和抽象类中都可以包含常量

public interface Flyable {

// 接口中所有的常量默认都是 public static final

public static final String TYPE = "可飞行" ;

}

public abstract class Flyer {

// Java 类中本来就可以声明常量

public static final String TYPE = "飞行物" ;

}

1.7. 接口和接口、抽象类和其它类之间的继承都使用 extends 关键字实现

public interface Moveable {

}

// 接口继承接口

public interface Flyable extends Moveable {

}

public abstract class Flyer {

}

// 抽象类继承抽象类

public abstract class Plane extends Flyer {

}

// 具体类继承抽象类

public class Aircraft extends Flyer {

}

接口和接口之间的继承、抽象类和抽象类之间的继承,以及抽象类和具体类之间的继承都使用 extends 关键字实现。

2、区别

2.1. 所有的抽象类都是Object类的子类,而接口则没有默认的最顶层父接口

( 注意这个区别是最重要的区别之一,凡是没有说明这一点的,都是不合适的 )

// 除非通过 extends 关键字显式指定了接口的父接口,否则接口默认没有父接口

public interface Flyable {

// 接口中所有的常量默认都是 public static final

public static final String TYPE = "可飞行" ;

}

// 对于抽象类而言,若未显式使用 extends 指定其父类,则其父类为java.lang.Object类

// 如果通过 extends 关键字显式指定了抽象类的直接父类,则其java.lang.Object类为其间接父类

public abstract class Flyer {

}

2.2. 抽象类只能有一个直接父类,接口可以父接口直接继承多个接口

( 注意这个区别是最重要的区别之一,凡是没有说明这一点的,都是不合适的 )

public interface Liveable {

void live();

}

public interface Moveable {

void move();

}

// 接口可以一次继承多个接口

public interface Flyable extends Moveable , Liveable {

}

public abstract class Flyer {

}

// 类只能继承一个直接父类

public class Kites extends Flyer {

}

// 尝试让一个类继承多个直接父类会导致编译错误

public class Airship extends Flyer , Object { // 编译错误

}

2.3. 抽象类有构造方法,接口没有构造方法

( 注意这个区别是最重要的区别之一,凡是没有说明这一点的,都是不合适的 )

抽象类首先是个类,是类就一定有构造方法:

public abstract class Flyer {

public Flyer() { // 显式声明的无参构造

super();

}

}

如果没有显式书写构造方法,编译器也会为抽象类添加一个公开的、无参的构造方法。

抽象类中的构造方法是供其直接子类调用的,并不是为了直接创建抽象类本身的实例准备的。

接口不是类,接口没有构造方法

public interface Flyable {

// 尝试为接口添加构造方法会导致编译错误

public Flyable() { // 编译错误

}

}

2.4. 接口中的成员变量只能是常量,抽象类中的成员变量可以是常量也可以是非常量

( 注意这个区别是最重要的区别之一,凡是没有说明这一点的,都是不合适的 )

public interface Flyable {

// 接口中所有的成员变量默认都是 public static final 修饰的

String TYPE = "可飞行" ; // 这里省略了 public 、static 、final 三个修饰符

String name ; // 编译错误 ( 因为默认有 final 修饰,必须显式赋值 )

}

public abstract class Flyer {

public static final String TYPE = "飞行物" ; // 常量

private static final String ENGINE = "引擎" ; // 常量

public static String brand ; // 类变量

private String name ; // 实例变量

}

2.5. 抽象内容不同

从OOAD角度看,抽象类是对某一类事物的抽象,是设计具体类的模板(属于数据结构范畴);

接口是对行为的抽象(属于行为规范范畴),实现该接口就表示该类事物可以具有某种行为特征。

2.6. 其它区别

接口中的抽象方法必须是 public访问级别,抽象类中的抽象方法可以是 public 、protected 、package-private 等访问级别

接口中的非抽象实例方法必须是 default 修饰符修饰,而抽象类中的非抽象实例方法一定不能用 default 修饰符修饰

抽象类可以继承(extends)指定父类并实现(implements)指定接口,接口只能继承(extends)接口(不能继承任何类)

如果以上区别也非要当作重大区别的话,那么还可以赠送两个区别:

接口使用 interface 关键字声明,抽象类使用 class 关键字声明并使用abstract修饰

汉语中,接口是两个字,抽象类是三个字; 英语中,interface 是一个词,abstract class 是两个词。并且不论汉语还是英语,每个字/每个词的写法都不一样。

因为写作时间仓促,错误和不当之处是在所难免的,欢迎大家批评指正!

写作背景:

2008年被某浪删过几次博客后,后来很少写或者几乎不写博文,仅有的几篇公开的博文,也是为学生整理的学习笔记。

所以,原本不打算在简书发任何文章,仅仅作为一个看客,看看大家写的文章,必要的时点评一下,跟大家做个交流就好。

无奈最近几天看到一篇文章,标题是《接口(interface)和抽象类(abstract class)的区别是什么》,这边文章并没有抓住接口和抽象类的主要区别,因为写的挺像回事的,所以好多人继续照抄了这篇文章,导致两三天的时间里能多次看到名称相同、内容相同的文章。

将别人整理的文章为我所用是可以的,关键是你得琢磨琢磨他写的对不对,最要命的是给他们点评后,他们根本不予理会,甚至把给它们的评论直接删除了。

为了避免有更多的后来者以讹传讹,所以写了这片博文。

因为写作时间仓促,错误和不当之处是在所难免的,欢迎大家批评指正!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值