本文是本人学习网络上各位大牛的总结。
一、抽象类
- 在面向对象领域由于抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能实例化的。
- 抽象类体现了数据抽象的思想,是实现多态的一种机制。它定义了一组抽象的方法,至于这组抽象的方法的具体表现形式由派生类来实现。同事抽象类提供了继承的概念,他的出发点就是为了继承,否则它没有存在的任何意义。所以说定义的抽象类一定是用来继承的。
-
使用抽象类时需要注意以下几点:
- 抽象类不能被实例化,实例化的工作应该交由它的子类来完成,它只需要一个引用即可;
- 抽象方法必须由子类来进行重写;
- 只要包含一个抽象方法的抽象类,该方法必须要定义成抽象类,不管是否还包含其他方法;
- 抽象类中可以包含具体的方法,当然也可以不包含抽象方法;
- 子类的抽象方法不能与父类的抽象方法同名;
- abstract不能与final并列修饰同一个类;
- abstract不能与private、static、final或native并列修饰同一个方法;
- 创建抽象类和抽象方法非常有用,因为他们可以使类的抽象性明确起来,并告诉用户和编译器打算怎样使用它们,抽象类还是有用的冲枸杞,因为他们使我们可以很容易地将公共方法沿着继承层次结构向上移动。
二、接口
- 接口本身就不是类,从我们不能实例化一个接口就可以看出;
- 实现该接口的实现类必须要实现该接口的所有方法;
-
使用接口过程中需要注意如下几个问题:
- Interface中的所有方法访问权限自动被声明为public。确切的说只能为public,当然你可以显式的声明为protected、private,但是编译会报错。
- 接口中可以定义“成员变量”,或者说是不可变的常量,因为接口中的“成员变量”会自动变为public static final。可以通过类命名直接访问:ImplementClass.name.
- 接口中不存在实现的方法;
- 实现接口的非抽象类必须要实现该接口的所有方法。抽象类可以不用实现。
- 不能使用new操作符实例化一个接口,但可以声明一个接口变量,该变量必须引用一个实现该接口的类对象。可以使用instanceof检查一个对象是否实现了某个特定的接口。
- 在实现多接口的时候一定要避免方法名的重复。
三、异同
相同点
- 代表系统的抽象层,当一个系统使用一颗继承树上的类时,应该尽量把引用变量声明为继承树的上层抽象类型,这样可以提高两个系统之间的松耦合;
都不能被实例化;
- 都包含抽象方法,这些抽象方法用于描述系统能提供那些服务,但不提供具体的实现。
不同点
- 在抽象类中可以为部分方法提供默认的实现,从而避免在子类中重复实现它们,这是抽象类的有事,但是这一优势限制了多继承,而几口中只能包含抽象方法。由于在抽象类中允许加入具体方法,因此扩展抽象类的功能,即向抽象类中添加具体方法,不会对它的子类造成影响,而对于接口,一旦接口被公布,就必须非常稳定,因为随意在接口中添加抽象方法,会影响到所有的实现类,这些实现类要么实现新增的抽象方法,要么声明为抽象类;
- 一个类只能继承一个直接的父类,这个父类可能是抽象类,但一个类可以实现多个接口,这是接口的优势,但这一优势是以不允许为任何方法提供实现作为代价的。
四、使用接口和抽象类的总体原则
- 用接口作为系统与外界交互的窗口站在外界使用者(另一个系统)的角度,接口向使用者承诺系统能提供哪些服务,站在系统本身的角度,接口指定系统必须实现哪些服务,接口时系统中最高层析次的抽象类型。通过接口交互可以提高两个系统之间的松耦合,系统A通过系统B进行交互,是指系统A访问系统B时,把引用变量声明为系统B中的接口类型,该引用变量引用系统B中接口的实现类的实例;
- Java接口本身必须非常稳定,Java接口一旦指定,就不允许随意更改,否则对外面使用者及系统本身造成影响;
用抽象类来定制系统中的扩展点,抽象类来完成部分实现,还要一些功能通过它的子类来实现。