java夯实基础系列:接口与抽象类

来源:互联网 发布:数据交换架构 编辑:程序博客网 时间:2024/06/01 11:07

一.接口

  接口在Java当中是通过关键字interface来实现,接口不是类,所以也不能被实例化,接口是用来建立类与类之间的协议,它的提供的只是一种形式,而没有具体的实现。实现类实现(implements)接口,必须实现接口的全部方法
  接口是抽象类的延伸,Java不允许多重继承(即不能有多个父类,只能有一个),但可以实现多个接口。在使用接口的过程中,就注意以下几个问题:

  • 接口中不能有构造方法。
  • 接口的所有方法自动被声明为public,而且只能为public,如果使用protected、private,会导致编译错误。
  • 接口可以定义”成员变量”,而且会自动转为public final static,即常量,而且必须被显式初始化。
  • 接口中的所有方法都是抽象方法,不能包含实现的方法,也不能包含静态方法
  • 实现接口的非抽象类必须实现接口的所有方法,而抽象类不需要
  • 不能使用new来实现化接口,但可以声明一个接口变量,它必须引用一个实现该接口的类的对象,可以使用instanceOf来判断一个类是否实现了某个接口,如if (object instanceOf ClassName){doSth()};
    在实现多接口的时候一定要注意方法名的重复

  接口相关内容很简单,这里主要分析一下接口的作用和好处,以下是知乎的一个关于接口的问题,曾经你是否也要这样的疑问呢?

例如我定义了一个接口,但是我在继承这个接口的类中还要写接口的实现方法,那我不如直接就在这个类中写实现方法岂不是更便捷,还省去了定义接口?接口在java中的作用是什么?个人觉得只是一种规范。大家的看法呢?

得票最高的答案:

能问这个问题,说明(1)你很会思考(2)编程水平还是处于起步阶段。

“接口是个规范”,这句没错。
“不如直接就在这个类中写实现方法岂不是更便捷”,你怎么保证这个接口就一个类去实现呢?如果多个类去实现同一个接口,程序怎么知道他们是有关联的呢?

既然不是一个类去实现,那就是有很多地方有用到,大家需要统一标准。甚至有的编程语言(Object-C)已经不把接口叫 interface,直接叫 protocol。

统一标准的目的,是大家都知道这个是做什么的,但是具体不用知道具体怎么做。
比如说:
我知道 Comparable 这个接口是用来比较两个对象的,那么如何去比较呢?
数字有数字的比较方法,字符串有字符串的比较方法,学生(自己定义的类)也有自己的比较方法。

然后,在另外一个负责对象排序(不一定是数字喔)的代码里面,肯定需要将两个对象比较。
这两个对象是什么类型呢?
Object a,b?肯定不行,a > b 这样的语法无法通过编译。
int a,b?也不行?一开始就说了,不一定是数字。
….
所以,Comparable 就来了。他告诉编译器,a b 两个对象都满足 Comparable 接口,也就是他们是可以进行比较的。具体怎么比较,这段程序不需要知道。
所以,他需要一些具体的实现,Comparable 接口有一个方法,叫 compareTo。那么这个方法就是用来取代 <、> 这样的运算符。
因为运算符是编译器保留给内置类型(整数、浮点数)进行比较用的,而不是一个广义的比较运算。

如果你可以明白 JDK 自身库里面诸如 Comparable 这样已经有的接口,那么就很容易理解自己在开发程序的时候为什么需要用到接口了。

见:https://www.zhihu.com/question/20111251

接口好处

  1. 接口是一些对外暴露的规则
    以usb接口为例,不管什么样的外部设备,都可以插入到usb解耦上去,对应到java中,一批实现了同一个接口的类,他们是具备某种同一特质的,很容易实现多态。

  2. 提高了程序的扩展性
    还拿usb来说,如果没有usb接口,鼠标怎么办?usb接口不紧可以插入鼠标,还可以插入移动硬盘。

  3. 降低了类之间的依赖关系(耦合性)
    我们通过一些实际的例子给大家形象讲解一下
    笔记本对外暴露接口,他不暴露不挺好的吗,也可以工作呀,但是紧跟着你发现一个问题,我想升级,硬盘升级到500g,怎么办,只能买一个新的。
    不过厂商想了一个方法,想扩展,不用拆我的电脑。侧面开了一个口,usb接口,你只要买一个硬盘,支持我这个口,就可以用,然后你买了一个500g的移动硬盘,往上咔嚓一插就可以用了。哪个usb是不是功能扩展,是不是对外规则,他是不是就降低了移动硬盘和电脑的耦合性。鼠标也是,是不是降低了鼠标和笔记本的耦合性呀。

继承和接口有何不同

有一个非常形象的例子
同学都有一些动作,学习呀,休息呀,我分析完,我发现很多学生抽烟。

接口他也属于共性的东西的,但是不是属于同一类,这个时候使用接口,是体系以外的功能扩展。接口是功能扩展用的,实现由子类来

继承是is-a,而接口是like-a,你像我中的一个。

比如很多学生抽烟这件事,抽烟就作为接口

来自think in java的忠告

  “确定接口是理想选择,因而应该总是选择接口而不是具体的类”。这其实是一种诱惑。当然,对于创建类,几乎在任何时候,都可以替代为创建一个接口和一个工厂。

  许多人都掉进了这种诱惑的陷阱,只要有可能就去创建接口和工厂。这种逻辑看起来好像是因为需要使用不同的具体实现,因此总是应该添加这种抽象性。这实际上已经变成了一种草率的设计优化。

  任何抽象性都应该是应真正的需求而产生的。当必需时,你应该重构接口而不是到处添加额外的级别的间接性,并由此带来的额外的复杂性。这种额外的复杂性非常显著。

  恰当的原则应该是优先选择类而不是接口。从类开始,如果接口的必需性变得非常明确,那么就进行重构。接口是一种重要的工具,但是它们容易被滥用。

二.抽象类

比较容易理解

抽象类是用来描述抽象行为的,比如Animal,我们不知道Animal具体有会有什么样的行为,只有具体的动物类,如Dog,Cat才有具体的行为,才能够被实例化。抽象类是实现多态的一种机制,它可以包含具体方法(有具体实现的方法),也可以包含抽象方法,而继承它的子类必须实现这些方法,下面总结了一下抽象类的特性:

  • 抽象类不能被实例化,但可以有构造函数
  • 抽象方法必须由子类进行重写
  • 只要包含一个抽象方法的类,就必须定义为抽象类,不管是否还包含其他方法
  • 抽象类中可以包含具体的方法,也可以不包含抽象方法
  • 抽象类可以包含普通成员变量,其访问类型可以任意
  • 抽象类也可以包含静态成员变量,其访问类型可以任意
  • 子类中的抽象方法不能与父类的抽象方法同名
  • abstract不能与private、static、final或native并列修饰同一个方法

三.接口和抽象类的区别

参考资料

http://www.jianshu.com/p/2b5a9bdcd25f

0 0