最近在看设计模式,感觉需要先好好区分下抽象类和接口。

一、抽象类

  《Java编程思想》中这样定义:包含抽象方法的类叫做抽象类。

  解释:

  1、包含,说明抽象类中可以有其他的具体方法。

  2、因为抽象方法的存在,所以抽象类不能实例化。

二、接口

  接口是用来建立类与类之间的协议,只提供抽象方法,不提供任何具体实现。

  特点:

  1、所有方法法访问权限自动被声明为public。确切的说只能为public,当然你可以显示的声明为protected、private,但是编译会出错!

  2、接口中可以定义“成员变量”,或者说是不可变的常量,因为接口中的“成员变量”会自动变为为public static final。

三、区别

  要从两个方面区别。

1、语法方面

  这个是面试时经常需要背会的,总结如下:

  1)抽象类可以提供成员方法的具体实现,而接口只能存在public abstract方法;

  2)抽象类中成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;

  3)一个类只能继承一个抽象类,而一个类却可以实现多个接口。

2、设计方面

  抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。eg:飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。那么在设计的时候,可以将飞机设计为一个类Airplane,将鸟设计为一个类Bird,但是不能将 飞行 这个特性也设计为类,因此它只是一个行为特性,并不是对一类事物的抽象描述。此时可以将 飞行 设计为一个接口Fly,包含方法fly( ),然后Airplane和Bird分别根据自己的需要实现Fly这个接口。然后至于有不同种类的飞机,比如战斗机、民用飞机等直接继承Airplane即可,对于鸟也是类似的,不同种类的鸟直接继承Bird类即可。从这里可以看出,继承是一个 "是不是"的关系,而 接口 实现则是 "有没有"的关系。

看设计模式的时候,总是说面对接口编程,有时候会不自觉的觉得什么都设计成接口会比较好,不过接口的问题在于:如果接口新增了一个方法,所有的实现类都得改动。基于这一点,我们来看一个网上常举的例子:

我们有一个Door的抽象概念,它具备两个行为open()和close(),此时我们可以定义通过抽象类和接口来定义这个抽象概念:

抽象类:

abstract class Door {
public abstract void open();
public abstract void close();
}

接口:

interface Door {
public abstract void open();
public abstract void close();
}

  需求:需要特定的一种门具备报警功能,如何实现?

  初步解决方案一:给door增加一个报警方法,clarm()

  1)如果都放在抽象类里面,这样一来所有继承于这个抽象类的子类都具备了报警功能。

  2)将这三个功能都放在接口里面,需要用到报警功能的类就需要实现这个接口中的open( )和close( ),也许这个类根本就不具备open( )和close( )这两个功能,比如火灾报警器。

  上面的方案,违背了设计模式中一个原则--接口隔离原则(Interface Segregation Principle):

  推荐方案:

  如果看过设计模式,就很容易想到下面方案了。

  单独将报警设计为一个接口,包含alarm()行为,Door设计为单独的一个抽象类,包含open和close两种行为。再设计一个报警门继承Door类和实现Alarm接口。

interface Alram {
void alarm();
} abstract class Door {
void open();
void close();
} class AlarmDoor extends Door implements Alarm {
void oepn() {
//....
}
void close() {
//....
}
void alarm() {
//....
}
}

四、总结

  1、 抽象类在java语言中所表示的是一种继承关系,一个子类只能存在一个父类,但是可以存在多个接口。

2、 在抽象类中可以拥有自己的成员变量和非抽象类方法,但是接口中只能存在静态的不可变的成员数据(不过一般都不在接口中定义成员数据),而且它的所有方法都是抽象的。

3、抽象类和接口所反映的设计理念是不同的,抽象类所代表的是“is-a”的关系,而接口所代表的是“like-a”的关系。

抽象类和接口是java语言中两种不同的抽象概念,他们的存在对多态提供了非常好的支持,虽然他们之间存在很大的相似性。但是对于他们的选择往往反应了对问题域的理解,这也是看设计模式之前必须要好好弄懂的一对概念,接下来我将分享我看设计模式的心得体会。

设计模式基础--Java接口和抽象类的更多相关文章

  1. 初探设计:Java接口和抽象类何时用?怎么用?

    今天犯了个错: “接口变动,伤筋动骨,除非你确定只有你一个人在用”.哪怕只是throw了一个新的Exception.哈哈,这是我犯的错误. 一.接口和抽象类 类,即一个对象. 先抽象类,就是抽象出类的 ...

  2. Java接口和抽象类有什么区别,哪些时候用接口,哪些时候用抽象类?

    Java接口和抽象类有什么区别,哪些时候用接口,哪些时候用抽象类? 2013-01-05 17:16:09|  分类: JAVA |  标签:java  |举报|字号 订阅     下面比较一下两者的 ...

  3. java 接口和抽象类的区别

    java 接口和抽象类的区别抽象类:1.含有抽象方法的类一定为抽象类,反过来抽象类,不一定含有抽象方法:2.抽象类必须用abstract来进行定义,抽象方法也必须用abstract来进行定义:3.抽象 ...

  4. 【Java基础】接口和抽象类之间的对比

    Java 中的接口和抽象类之间的对比 一.接口 Interface,将其翻译成插座可能就更好理解了.我们通常利用接口来定义实现类的行为,当你将插座上连接笔记本的三角插头拔掉,换成微波炉插上去的时候,你 ...

  5. Java基础之接口与抽象类及多态、内部类

    final关键字 被其修饰的类,不能被继承. 被其修饰的方法,不能被覆盖. 被其修饰的变量,是一个常量,不能被修改,所以定义时必须初始化(和C++的const类似). 一般有final,会搭配stat ...

  6. Java基础——关于接口和抽象类的几道练习题

    呃,一定要理解之后自己敲!!!这几道题,使我进一步了解了接口和抽象类. 1.设计一个商品类 字段: 商品名称,重量,价格,配件数量,配件制造厂商(是数组,因为可能有多个制造厂商) 要求: 有构造函数 ...

  7. Java基础(四)--接口和抽象类

    接口和抽象类能够体现OOP的抽象,而接口和抽象类也是日常开发中经常用到的 抽象方法: 抽象方法就是被abstract修饰的方法,只有声明,没有实现,也就是没有方法体 public abstract v ...

  8. 《Java基础知识》Java接口和抽象类的区别

    抽象类 抽象类必须用 abstract 修饰,子类必须实现抽象类中的抽象方法,如果有未实现的,那么子类也必须用 abstract 修饰.抽象类默认的权限修饰符为 public,可以定义为 public ...

  9. java接口和抽象类

    关于接口 1.创建一个接口,需要使用interface关键字. 2.实现一个接口,需要使用implements关键字. 3.接口的成员属性都是静态常量(默认public static final). ...

随机推荐

  1. Jmeter的BeanShell中报错:调用bsh方法时出错Error invoking bsh method: eval

    报错内容:ERROR - jmeter.util.BeanShellInterpreter: Error invoking bsh method: eval In file: inline evalu ...

  2. JavaScript跨域资源请求(CORS)解决方案

    跨域:当协议.主域名.子域名.端口号中任意一个不相同时都不算同一个域,而在不同域之间请求数据即为跨域请求.解决方法有以下几种(如有错误欢迎指出)以请求图片url为例: 1.通过XMLHttpReque ...

  3. Murano 网址一览

    [Murano_Meeting] http://eavesdrop.openstack.org/#Murano_Meeting [Murano_Meeting_Agenda] https://wiki ...

  4. Java微信公众平台开发(十)--微信用户信息的获取

    前面的文章有讲到微信的一系列开发文章,包括token获取.菜单创建等,在这一篇将讲述在微信公众平台开发中如何获取微信用户的信息,在上一篇我们有说道微信用户和微信公众账号之间的联系可以通过Openid关 ...

  5. Linux安装配置相关

    1.常用汇总 useradd usertemp //添加用户 passwd usertemp //修改/设置密码 userdel usertemp //删除用户 2. profile/baserc等配 ...

  6. Hibernate的工作流程以及三种状态(面试题)

    Hibernate的工作流程以及三种状态 部分转载自:http://www.cnblogs.com/fifiyong/p/6390699.html Hibernate的工作流程: 1. 读取并解析配置 ...

  7. strstr strcpy 函数的实现

    一. strcpy 代码实现 #include <iostream> #include <assert.h> #include <iostream> //#incl ...

  8. windows 2012 r2 x64 安装IIS注意事项

    详细安装可以参考下面; https://jingyan.baidu.com/article/93f9803f234eade0e46f559f.html 下面只说一些注意事项,如果项目要用到wcf 的话 ...

  9. (转)IE6 死后即将大快人心的10件事

    (转)未来五年程序员应当具备的十项技能 W3C CSS 2.1 Specification(Quick Table of Contents) (转)IE6 死后即将大快人心的10件事 2009-04- ...

  10. JS实现2048

    2048这个游戏是通过对二维数组的操作来实现的,其算法核心如下: (以一行左移为例) c从0开始,遍历当前行中的元素,到<CN-1(CN是一个常量,表示的是游戏格子的列数)结束,每次+1 找到当 ...