2009-01-27

再谈Java中的类、抽象类和接口还有Object类

  放假了,趁着这个机会温故而知新,在读书的过程中,理一理自己的知识体系。唉,悲叹一下由于上个学期把大部分时间花在计算机技术上了,没有花多少时间在本专业的课程上,导致下个学期要达到我的目标需要付出大量的时间了。。。。引以为戒啊。
 
  刚才读的是Java的多态,Head First Java的作者引出概念的方法相当高明,让人浅显易懂,概括起来:

类与抽象类:
  本来,一个类继承了父类,那么就表明,在这个继承体系中,父类比较抽象,子类比较具体一点。但是在很多情况下,不应该存在父类的实例,也就是父类不应该被实例化。就像有具体的各种动物,但是一个叫做animal的实例不应该存在。因此就有必要有抽象类。它不能被实例化。
  从程序的规则上来说,一个类中,只要有一个抽象的方法就必须把这个类声明为抽象类,而一个抽象类中除了抽象的方法也可以有有实现的方法。另外,一个抽象方法必须要有最终实现它的子类的对应的方法。

类与接口:
  在一群继承自同一个父类A的子类中,有一部分不仅和A有着IS-A的关系,还和另外一个类B有着IS-A的关系,这种时候我们不应该把A和B合并,因为这样导致那些没有B特征的A特征的子类也需要被迫继承B的特性,所以只能让那些同时和AB有着IS-A关系的子类同时继承A和B两个类,但是这个时候难题就出现了,如果这些同时和AB有着IS-A关系的子类同时继承A和B两个类的话,会出现多重继承的很多麻烦的问题,在JAVA中,也不允许多重继承,但是在Java中替代的解决方案就是interface。
  一个类可以继承自一个父类,但同时允许实现多个接口,而不同继承树的类可以实现同样的接口。这里的接口可以看作是纯粹的抽象类,其所有方法都是抽象的。


所以,在设计中,判别继承树的时候可以通过考虑一下问题来确定使用的是抽象类还是接口:

  • 如果要定义一群子类的模板(因此模板不应该被初始化),就使用抽象类
  • 如果要定义出类可以扮演的角色,就使用接口。

  了解了以上关系,Java的整个多态性的结构就初具雏形了。这里就很自然的引出了另外一个问题:Java的终极类——Object类在整个Java中的作用。

  众所周知,Object类是Java中所有类源头。它的存在,使得程序员可以写出能够处理所有类型的通用类。但是有趣的是,Object不是抽象类,它允许被创建出实例,Object的主要目的在于作为多态,让方法可以应付多种类型;提供Java在运行时对任何对象都有需要的方法的实现。

  但是,显然我们不应该极端到随便把参数和返回类型设定为Object,因为一个被认定为Object的引用的实例是无法调用非Object类所有的方法的。当然我们可以通过强制类型转换来处理,但是这样太暴力了。。。很可能导致程序健壮性上的问题。。。

没有评论: