首页 > 代码库 > 接口与抽象类

接口与抽象类

首先声明,本文基本参考自
http://dev.yesky.com/436/7581936.shtml
加入从其他资料中获得的观点。

1从逻辑上说

   抽象类描述了一系列"东西"的本质。
   接口描述一系列"东西"应该具有的功能,或者说接口就是一组契约。
   在oop的观点里,世界上任何实物都能在思想的角度给一个类与之配对,但反过来说,并不是思想中所有的类都能在现实世界里找到一个实物配对。(这里说的思想里的类 也是个逻辑概念 包括普通的类也包括抽象类 接口等等)
举个例子,我们设计一个绘图软件,这里面会有正方形三角形,直线曲线,实线虚线,红色蓝色各种逻辑概念。我们现在只讨论正方形三角形这个问题域,通过对这个问题域的思考,我们能设计出一个"形状"的概念,我们能从绘图软件的侧边栏拖出一个三角形一个正方形,但是我们不能拖出一个"现状"!因为在我们的问题域里其实不存在"形状"的概念,它是我们抽象出来的。既然是抽象的自然就不能实例化喽!

2从语法定义上说

   abstract class Demo{
   abstract void meth1();
   abstract void meth2();
   }
   interface Demo2{
   void meth1();
   void meth2();
   }
最基本的定义如上。
一个类只可以继承一个类,却可以实现很多个接口(多少个? 好像是65535 估计够咱们用了)
先说属性,抽象类中可以有自己的数据成员。接口中也可以有数据成员,不过都是static final型的,另外虽然接口从语法角度可以有属性,但是实际情况中,我们并不在接口中定义属性。
再说方法,接口中的所有的方法都是抽象的(不能有方法体),且都默认是public。抽象类中的方法可以有方法体,也可以没有方法体(没有方法体时要注明abstract)
抽象类中的抽象方法(其前有abstract修饰)不能用private、static、synchronized、native访问修饰符修饰。原因如下:抽象方法没有方法体,是用来被继承的,所以不能用private修饰;static修饰的方法可以通过类名来访问该方法(即该方法的方法体),抽象方法用static修饰没有意义;使用synchronized关键字是为该方法加一个锁。。而如果该关键字修饰的方法是static方法。则使用的锁就是class变量的锁。如果是修饰 类方法。则用this变量锁。但是抽象类不能实例化对象,因为该方法不是在该抽象类中实现的。是在其子类实现的。所以。锁应该归其子类所有。所以。抽象方 法也就不能用synchronized关键字修饰了;native,这个东西本身就和abstract冲突,他们都是方法的声明,只是一个吧方法实现移交给子类,另一个是移交给本地操作系统。如果同时出现,就相当于即把实现移交给子类,又把实现移交给本地操作系统,那到底谁来实现具体方法呢?
上一段参考资料
http://blog.sina.com.cn/s/blog_7ffb8dd5010111yu.html

3从设计层面来说

  在回忆一下上文的观点
   抽象类描述了一系列"东西"的本质。
   接口描述一系列"东西"应该具有的功能,或者说接口就是一组契约。
   现在我们设计了一个door,它具有open与close的功能,我们可以用抽象类的方式实现,也可以用接口的方式实现。
   如果我们现在又设计了一个带报警功能的门呢?
   方法一
        我们在原来的抽象类/接口中加上一个报警的方法(只有一个概念)
问题出现了,从逻辑上说,我们一直都在重复抽象类描述的事一系列东西的本质,报警算是门的本质么?应该不算吧。另外从软件的角度来看,我们确实存在一些类,它是单单依赖于门这个类的,现在我们把门改了加上了报警的特性,那么那些原本只依赖门open与close的类也得改。
   方法二
        把门和报警器设计成两个概念
1门和报警器都是抽象类
java中不允许多重继承。
2门和报警器都是接口
那带报警器的门罗逻辑上来说到底是门能还是接口呢?
"带报警器的门"从语法上分析,我们都能看出来"带报警器"是"门"的一个定语起修饰作用,带报警器的门的实质还是门。因此就有了第3中思路
        3门是抽象类,报警器是接口
显而易见,门是抽象类,报警器是接口这种方式是我们所需要的。


总而言之,设计层面上的东西没有对错之分,只有合适与否之别,上面的问题中,如果我们认为带报警器的门本质上是报警器同时又门的功能,那咱们就把程序设计成门市接口,报警器是抽象类即可!
言而总是,类的继承说的是" a ia b"的关系;类的实现说的是"a is like b"(a像b)的关系!

接口与抽象类