Java抽象类与接口的理解
abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力。
abstract class和interface之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进行抽象类定义时对于 abstract class和interface 选择显得比较随意。
其实,两者之间还是有很大的区别的,对于它们的选择甚至反映出对于问题领域本质的 理解、对于设计意图的理解是否正确、合理。本文将对它们之间的区别进行一番剖析, 试图给开发者提供一个在二者之间进行选择的依据。
编程规则上的区别
接口:
1:接口的命名规则与类型不同。如果修饰符是public。则该接口在整个项目中可见 ,如果省略修饰符 则该接口只能在该包可见
2:接口中可以定义常量,不能定义变量,接口中的属性都会自动用public static final修饰,即接口中的属性都是公用全局静态常量,接口中的常量必须在定义时指定初始值
3:接口中所有的方法抽象方法。接口中的方法都会自动用public abstract修饰。即接口中只有公用全局抽象方法(可省略大括号,直接;收尾 void onClickListener();//可以不用添加 public abstract
)
4:和抽象类一样,接口不能被实例化,接口中不能有构造方法(子类的super()就是调用父类的构造方法),但可以将实现该接口的类的对象赋值给该接口(多态的体现,抽象类也体现了多态)
5:接口之间可以通过extends 实现继承关系,一个接口可以继承多个接口。但接口不能继承类
6:接口的实现类必须实现接口的全部方法,否则必须定义为抽象类。抽象类也可以实现接口可以在该抽象类中实现接口方法,也可在其最终实现的子类中实现接口方法,其实现子类可以覆盖,也可以选择默认使用父类/抽象类中实现的接口方法。
7:一个类只能有一个直接父类,但可以通过implements实现多个接口,当类在继承父类的同时有实现了多个接口时,extends关键字必须位于implements关键字之前
抽象类:
1:如果一个类中有抽象方法,那么这个类一定是抽象类
2:抽象类中不一定有抽象方法
3:抽象类中可以存在抽象方法
4:抽象类中可以存在构造方法
5:抽象类中可以存在普通属性、方法、静态属性和静态方法
6:抽象类中的抽象方法需要有子类实现,如果子类不实现,则子类也需要定义为抽象的
7:抽象方法和抽象类都必须被abstract关键字修饰。
8:抽象类不可以用new创建对象。因为调用抽象方法没意义
9:抽象类中的抽象方法要被使用,必须由子类复写起所有的抽象方法
接口和抽象类的区别之处:
1:接口中所有的方法隐含都是抽象的,而抽象类则可以同时包含抽象和非抽象的方法
2:类可以实现很多个接口,但是只能继承一个抽象类
3:类可以不实现抽象类和接口声明的所有方法,在这种情况下,类也必须得声明成是抽象的
4:抽象类可以在不提供接口方法实现的情况下实现接口
5:java接口中声明的变量默认都是final的,抽象类可以包含非final变量
6:java接口中的成员函数默认都是public的,抽象类中的成员函数可以是private,protected或者是public的
7:接口是绝对抽象的,不可以被实例化。抽象类也不可以被实例化,但是如果它包含main方法的话是可以被调用的
8:抽象类中可以有普通方法,接口中不能。
9:抽象类可以有构造,接口不能
10:抽象类中可以有普通字段,而接口中不行
11:抽象类不能实现多继承,接口可以
12:符合isa关系的选用抽象类,符合hasa关系的选用接口比抽象类抽象程度更高
选择抽象类与接口的依据是什么
接口和抽象类的概念不一样。接口是对动作的抽象,抽象类是对根源的抽象。
抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。比如,男人,女人,这两个类(如果是类的话……),他们的抽象类是人。说明,他们都是人。
人可以吃东西,狗也可以吃东西,你可以把“吃东西”定义成一个接口,然后让这些类去实现它.
所以,在高级语言上,一个类只能继承一个类(抽象类)(正如人不可能同时是生物和非生物),但是可以实现多个接口(吃饭接口、走路接口)。
第一点. 接口是抽象类的变体,接口中所有的方法都是抽象的。而抽象类是声明方法的存在而不去实现它的类。
第二点. 接口可以多继承,抽象类不行
第三点. 接口定义方法,不能实现,而抽象类可以实现部分方法。
第四点. 接口中基本数据类型为static 而抽类象不是的。
当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。
抽象类的功能要远超过接口,但是,定义抽象类的代价高。因为高级语言来说(从实际设计上来说也是)每个类只能继承一个类。在这个类中,你必须继承或编写出其所有子类的
所有共性。虽然接口在功能上会弱化许多,但是它只是针对一个动作的描述。而且你可以在一个类中同时实现多个接口。在设计阶段会降低难度的。
从问题领域和设计理念的选择接口还是抽象类,结合设计模式分析
这篇文章结合了一个具体的案例去分析
总结
总的来说,接口和抽象类都能完成java的抽象工作,都能体现面向抽象编程思想,但何时选择抽象类
当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。
抽象类一般作为公共的父类为子类的扩展提供基础,这里的扩展包括了属性上和行为上的。
而接口一般来说不考虑属性,只考虑方法,使得子类可以自由的填补或者扩展接口所定义的方法