Java抽象类和接口的区别

来源:互联网 发布:js实现中奖后彩带特效 编辑:程序博客网 时间:2024/06/11 14:04

在Java中,abstract class和interface是支持抽象类定义的两种机制,也是Java面向对象的强大依赖:

  • 理解抽象类
  • OCP原则
  • 具体区别
  • 总结

抽象类

 在面向对象的概念中,对象都是通过类来描绘,但是反过来不是所有的类都用于描述对象,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类;抽象类往往用来表征我们在对问题领域进行分析、设计中得出的抽象概念,对一系列看上去不同,但是本质上相同的具体概念的抽象,比如圆形、正方形是具体概念,二者不同,但是他们属于图形,而图形这个概念在问题领域不存在,是一个抽象概念,正是因为抽象概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能实例化的。在面向对象领域,抽象类主要用来进行类型隐藏。可以构造出一个固定的一组行为的抽象描述,这组行为能够有任意个可能的具体实现方式,这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类,模块可以操作一个抽象体,由于模块依赖于一个固定的抽象体,因此他们可以是不允许修改的,同时通过这个抽象体派生,可扩展此模块的行为功能,为了能够实现面向对象设计的一个最核心原则OCP(开-闭原则见下),抽象类是关键所在;

OCP原则简述

对扩展开放,对修改关闭;优点,按照OCP原则设计出来的系统,降低了程序各部分之间的耦合性,其适应性、灵活性和稳定性都比较好,当一软件系统需要增加新的功能时,不需要对系统基础的抽象层进行修改,只需要在原有基础上附加新的模块就能实现所需要添加的功能,增加的新模块对原有的模块完全没有影响或者影响很小,这样就不用对原有模块进行测试;如何实现“开-闭原则”:在面向对象设计中,不允许更改的是系统抽象层,而运行扩展的是系统的实现层,也就是定义一个一劳永逸的抽象设计层,允许尽可能多的行为在实现层实现;解决问题的关键在于抽象化,抽象化是面向对象设计的第一个核心本质。对一个事物抽象化,实质上是在概括归纳他的本质,抽象让我们抓住最重要的东西,从更高层次思考,这降低了思考的复杂度,我们不用同时考虑那么多东西,换而言之就是封装了事物的本质,看不到任何细节;在面向对象编程中,通过抽象类及接口,规定了具体类的特征作为抽象层,相对稳定,不需更改,从而满足“对修改关闭”;而从抽象类导出的具体类可以改变系统的行为,从而满足“对扩展开放”;

接口

interface可以分为外部接口与内部接口(主要讨论外部接口);外部接口有public修饰和无public修饰,使用public修饰的接口必须定义在同名的Java文件内,所有类访问(公共接口)。如果接口不在同名Java文件中定义,则无修饰符,此时只供同包内的类访问;类要实现interface,使用implements;类能使用接口里的成员,但是不能赋值,因为接口成员都是常量;接口可以实现不相关类的相同行为,提供不相同对象进行协作的平台,接口实现多继承弥补类的单继承;

具体区别

抽象类: 抽象方法,它只有声明,没有具体实现,abstract void fun(); 如果一个类含有抽象方法,则这个类为抽象类,必须使用abstract修饰特点:抽象方法必须为public或者protected(如果为private,则不能被子类继承,子类无法实现该方法),缺省情况下默认public;抽象类不能用来创建对象;如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法,如果没有实现,那么子类也定义为abstract接口: 接口中可以含有 变量和方法,但是接口中的变量会被隐式的指定为public static final变量,且必须给定初值(也只能是这个,用private修饰会报错)不过在interface中一般不定义数据成员,而方法会被隐式的指定为public abstract也只能是这个,接口中的方法不能有具体实现,也就是说,接口中的方法必须都是抽象方法;接口虽然不能实例化,但是能实现多态,也就是一个接口的引用变量可以指向实现它的类的一个对象(需要这个类实现接口且调用类重写后的方法),类似继承多态;接口可以继承接口(所有成员与方法),一个接口可以同时继承多个接口;接口的多继承会冲突1、接口继承的两个接口具有相同的名字的成员,这时需要指明想调用的是哪个成员,不能用this;2、另外的两个接口具有相同名字的方法;如果方法返回类型相同,这时不影响继承,需要重写方法(编译器将两个方法视为一个),如果返回类型不同,非抽象类不能实现该接口,因为一个非抽象类无法同时重写这两个方法,也就是说,一个类中不能有两个方法名字相同参数相同但是返回值不同吧,这种情况,emmm...为什么一定要一个类实现呢,分开写也是可以的;区别:在语法上,抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract方法;抽象类中的成员变量可以是各种类型,而接口中的成员变量只能是 public static final;接口中不能含有静态代码块以及静态方法,抽象类可以有;一个类只能继承一个抽象类,而一个类可以实现多个接口;实现抽象类和接口的类必须实现其中的所有方法,抽象类中可以有非抽象方法,接口中则不能有实现方法; 在设计上,抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象;抽象类对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部 (行为)抽象,abstract class表示的是“is-a”的关系,interface表示的是“like-a”; 举个简单的例子(这个例子参考自网络),飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。那么在设计的时候,可以将飞机 设计为一个类Airplane,将鸟设计为一个类Bird,但是不能将 飞行 这个特性也设计为类,因此它只是一个行为特性,并不是对一类事物的 抽象描述。此时可以将 飞行 设计为一个接口Fly,包含方法fly(),然后Airplane和Bird分别根据自己的需要实现Fly这个接口。然后至于 有不同种类的飞机,比如战斗机、民用飞机等直接继承Airplane即可,对于鸟也是类似的,不同种类的鸟直接继承Bird类即可。从这里可以 看出,继承是一个 "是不是"的关系,而 接口 实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类, 而接口实现则是有没有、具备不具备的关系,比如鸟是否能飞(或者是否具备飞行这个特点),能飞行则可以实现这个接口,不能飞行就不 实现这个接口;

总结

可能在上述抽象类和接口的介绍中出现部分重复累赘,(⊙﹏⊙)b汗!如有出现错误、参考而未注明出处的地方欢迎留言指正。

    • 抽象类
    • OCP原则简述
    • 接口
    • 具体区别
    • 总结


原创粉丝点击