RSS

面向对象设计里面的继承和接口问题

05 Dec

 

 

面向对象设计里面的继承和接口问题

一.   继承

继承强调的是is a 的关系,强调子类能够从父类继承属性.这种继承而来的属性应该是家族性的类,也就是说,这种属性应该是这种家族在语义上的标识.因此在这样的情况下,如果2个类之间有着很强的血缘关系(在语义上),并且共同有着维持着血缘关系的属性,则应该进行继承.

二.   接口

接口强调的是is able to的关系,接口继承强调的是能够实现接口所标识的那些方法.一般来说,接口里面是不要有属性的,也就是说,接口不能实例化,接口可以看作是一组能够实现做某些事情的类的集合,可以看作是一组提供服务的集合,并且接口并不限制这些类做事的方式,也就是说,接口是纯粹的为了多态而出现的一种类.

三.   用途

继承一般用在这样的情况下.

1.        在语义的层面上,2个类之间有着is a的关系,并且有着相同的标识这个家族的属性.

接口一般用在这样的情况下:

1.        在语义的层面上,2个类之间没有is a的关系.则一定是接口继承.

2.        一个类在语义上没有实例化的趋势,并且没有自己的属性,仅仅刻画了一组操作.

四.   矛盾和解决方案

但是在实际的是用过程中,很多情况都是很复杂的,上面的情况并没有涵盖所有在现实中可能出现的情况.例如:

如果2个类之间有着is a的关系,但是父类没有实例化的趋势,并且父类还有着自己的属性.比如在一个公司里面,有一个类Person,这个类是在公司的语境下是不会被实例化的,因为公司里面对于每个人都有着自己的职位的归属,不可能出现Person实例化出来的对象.Person的子类有2,一个是Boss,一个是Employer.

这样的情况,2个类之间有着is a的关系,但是父类没有实例化的趋势,这样的类的设计好像是不合理的,但是父类在语义上有着必要,并且在一定程度上也是刻画了家族的属性,比如说人都是有名字的,有年龄的,BossEmployer也不例外,因此他们实际上是应该继承自Person.但是这样的类在公司的语境下又不会被实例化,这样的类不是很诡异么?并且由于Person类不会被实例化,因此里面定义的所有的方法都是虚方法,这样的一个类,同时又有了接口的部分特征.

但是,由于Person类含有属性,因此不能将其设计为接口.

这样的情况下有2种设计方案.

方案一:

第一种解决方案

 

优点: 使用的类数量较少.为了可以进行多态的调用,在父类Person里面的函数不能为虚,因此为子类提供了一个默认的操作.可以用父类代替子类在很多地方进行表示.

缺点: 为了可以进行多态的调用,在父类Person里面的函数不能为虚,因此如果没有子类的默认的公共的操作的话,就是一个无用的函数.并且这样将加大子类对父类的依赖性,使得类之间的耦合度加大.以后如果父类改变,将对子类造成很大的影响.并且在理解上面造成混乱,不是很符合一般的想法.

方案二:

第二种方案

 

 

 

优点: 避免了在程序中有不能被实例化的类的调用,在多态的调用理解上面消除了混乱.因为这样的多态调用只有2种情况.一种是使用类名进行调用,这样的调用一定是类本身也带有自己的实现方法,并且其子类也有着自己的实现(不论有没有override).另一种是使用接口进行调用,这样的话就明确了是在进行多态的调用,请求的是一种服务.此外,减少了类之间的耦合,逼迫每个子类有自己的实现,只在属性上对父类进行继承,而把依赖建立在更稳定的接口之上.

缺点:使用的类和接口较多,容易代码膨胀.很多地方不能使用父类代替子类,因为子类有着父类没有的方法.也就是说,进行与子类的交互的时候,必须通过接口.

 

Advertisements
 
Leave a comment

Posted by on December 5, 2009 in Technical notes

 

Tags: , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: