Java抽象类与接口的区别

很多常见的面试题都会出诸如抽象类和接口有什么区别,什么情况下会使用抽象类和什么情况你会使用接口这样的问题。本文我们将仔细讨论这些话题。

在讨论它们之间的不同点之前,我们先看看抽象类、接口各自的特性。

抽象类

抽象类是用来捕捉子类的通用特性的 。它不能被实例化,只能被用作子类的超类。抽象类是被用来创建继承层级里子类的模板。以JDK中的GenericServlet为例:

1
2
3
4
5
6
7
8
9
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
    // abstract method
    abstract void service(ServletRequest req, ServletResponse res);
 
    void init() {
        // Its implementation
    }
    // other method related to Servlet
}

当HttpServlet类继承GenericServlet时,它提供了service方法的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class HttpServlet extends GenericServlet {
    void service(ServletRequest req, ServletResponse res) {
        // implementation
    }
 
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        // Implementation
    }
 
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
        // Implementation
    }
 
    // some other methods related to HttpServlet
}

接口

接口是抽象方法的集合。如果一个类实现了某个接口,那么它就继承了这个接口的抽象方法。这就像契约模式,如果实现了这个接口,那么就必须确保使用这些方法。接口只是一种形式,接口自身不能做任何事情。以Externalizable接口为例:

1
2
3
4
5
6
public interface Externalizable extends Serializable {
 
    void writeExternal(ObjectOutput out) throws IOException;
 
    void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
}

当你实现这个接口时,你就需要实现上面的两个方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Employee implements Externalizable {
 
    int employeeId;
    String employeeName;
 
    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        employeeId = in.readInt();
        employeeName = (String) in.readObject();
 
    }
 
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
 
        out.writeInt(employeeId);
        out.writeObject(employeeName);
    }
}

抽象类和接口的对比

参数 抽象类 接口
默认的方法实现 它可以有默认的方法实现 接口完全是抽象的。它根本不存在方法的实现
实现 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。 子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现
构造器 抽象类可以有构造器 接口不能有构造器
与正常Java类的区别 除了你不能实例化抽象类之外,它和普通Java类没有任何区别 接口是完全不同的类型
访问修饰符 抽象方法可以有publicprotecteddefault这些修饰符 接口方法默认修饰符是public。你不可以使用其它修饰符。
main方法 抽象方法可以有main方法并且我们可以运行它 接口没有main方法,因此我们不能运行它。
多继承 抽象方法可以继承一个类和实现多个接口 接口只可以继承一个或多个其它接口
速度 它比接口速度要快 接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。
添加新方法 如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。 如果你往接口中添加方法,那么你必须改变实现该接口的类。

什么时候使用抽象类和接口

  • 如果你拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类吧。
  • 如果你想实现多重继承,那么你必须使用接口。由于Java不支持多继承,子类不能够继承多个类,但可以实现多个接口。因此你就可以使用接口来解决它。
  • 如果基本功能在不断改变,那么就需要使用抽象类。如果不断改变基本功能并且使用接口,那么就需要改变所有实现了该接口的类

Java第五周总结的更多相关文章

  1. 20165210 Java第五周学习总结

    20165210 Java第五周学习总结 教材学习内容 - 第七章学习总结 内部类: 内部类的外嵌类的成员变量在内部类中仍然有效,内部类中的方法也可以调用外嵌类中的方法. 内部类的类体中不可以声明类变 ...

  2. JAVA 第五周学习总结

    20175303 2018-2019-2 <Java程序设计>第五周学习总结 教材学习内容总结 •使用关键字interface来定义一个接口,定义接口分包含接口声明和接口体. •接口体中包 ...

  3. 20165221 JAVA第五周学习心得

    课本知识点 内部类与异常类 内部类:在一个类中定义另一个类 特点:外嵌类的成员在内部类仍然有效,内部类也可调用外嵌类的方法,内部类的类体不能声明类变量及类方法 非内部类不能是static类 匿名类:创 ...

  4. 20165326 java第五周学习笔记

    第五周学习笔记 ch7 内部类(&外嵌类) 内部类的类体不可以声明类变量和方法 内部类如同类的变量或方法 内部类和外嵌类在编译时生成两个class文件 匿名类 某个类的一个子类没有明显的用类声 ...

  5. Java第五周学习总结

    学号 2016-2017-2 <Java程序设计>第X周学习总结 教材学习内容总结 1.接口 (1)使用关键字interface来定义一个接口,接口分为接口声明和接口体,例如 interf ...

  6. 20165220 Java第五周学习总结

    教材学习内容总结 1.try—catch语句:Java用try—catch语句来处理异常.将可能出现的异常操作放在try中,当try出现异常时,此部分立刻结束运行,转向执行catch部分.一个try- ...

  7. 自学Java第五周的总结

    在这周里我在我要自学网上观看视频学习了有关java的基础知识,课程主要介绍JavaSE,这是整个Java体系的基础:课程将由浅入深,并结合案例进行讲解,在那里我将自己已学的知识进行了巩固,并由学习到了 ...

  8. 2016-2017-2 20155309南皓芯java第五周学习总结

    教材内容总结 这一周学习的进度和前几周比较的话是差不多的,都是学习两章. 异常处理 1.理解异常架构 2.牚握try...catch...finally处理异常的方法 3.会用throw,throws ...

  9. Java第五周作业+总结

    实验三 String类的应用 实验目的 掌握类String类的使用: 学会使用JDK帮助文档: 实验内容 1.已知字符串:"this is a test of java".按要求执 ...

  10. java第五周学习

    在Java中类与类之间的关系 1.聚合关系 : 两个类的关联程度较低,可以单独存在. 2.组合关系 : 两个的关联程度比较高. Java中如何来表现这个关系. 一类A作为属性存在类B中. 3.依赖关系 ...

随机推荐

  1. PHP 轻量级 REST框架

    GITHUB:https://github.com/jacwright/RestServer 简介: 一个PHP REST服务器,用于提供非常轻量级的REST API.很容易上手.独立于其他库和框架. ...

  2. vue 路由(1)

    路由的使用  (5步) 1.首先安装路由  npm install  vue-router2.引入 vue-router import VueRouter from 'vue-router' 3.使用 ...

  3. linux(ubuntu)GCC编译包含库函数的问题

    GCC 编译命令通常为:gcc hello.c -o hello.out 注意:若hello.c中引用有库函数(比如math.h),直接编译会出错 "/tmp/ccalvMPY.o: In ...

  4. spring boot hello world

    本文讲解初始用户搭建spring boot 工程. 新建工程目录结构: application.java放在最外层的包目录里 先添加pom.xml的依赖包: <project xmlns=&qu ...

  5. linux驱动由浅入深系列:PBL-SBL1-(bootloader)LK-Android启动过程详解之一(高通MSM8953启动实例)

    转自:http://blog.csdn.net/radianceblau/article/details/73229005 http://www.aiuxian.com/article/p-14142 ...

  6. python 全栈开发笔记 1

    将自己的姓名用进制表示出来 #自己姓名的进制表示 name=input('请输入你的名字:') for i in name: print(i) # python 3 中是按字符进行循环的 bytes_ ...

  7. QSSP软件一些参数的设置(远震波形合成)

    1.time window, sampling interval 这里需要注意的是两者的和必须是2的n次方,可以写成2047 1; 2046 2,或2047.75 0.25,2047.9 0.1等等 ...

  8. L362 When to Bring up Salary During the Job Interview Process

    Money is an awkward topic of conversation for many professionals—even more so when you’re busy tryin ...

  9. Linux 下使用umount强行卸载设备

    卸载NFS,结果出现无法卸载的情况 [root@localhost /]# umount /udisk/ umount: /udisk: device is busy umount: /udisk: ...

  10. full visualization vs part virtualization

    https://stackoverflow.com/questions/21462581/what-is-the-difference-between-full-para-and-hardware-a ...