论坛首页 入门技术论坛

从接口继承还是从抽象类继承

浏览 3749 次
该帖已经被评为新手帖
作者 正文
   发表时间:2007-11-10  

需求设计:
某工人对车床进行100天的检测,对车床的检测状况进行打分。
车床现有3种不同类型的车床,各自参数不同。分为A, B, C三类。
该工人每天对不同的车床参数进行登记。

记分状况如下:
如A车床上次登记时间为2007-10-10 10:23:32,现在为2007-10-12 11:23:34,原记分情况为49分,因为差距为2天,因此记分扣除2分;B车床上次登记时间为2007-10-12 11:20:21,现在为2007-10-12 11:39:32,原记分为38分,因不满1天,所以该车床记分改为39,增加1分。

抽象的方式有两种,其一为抽象成接口,由A、B、C来实现;另一种则为抽象成抽象类,分别由A、B、C类来继承。考虑可增加新的车床类,和修改现有记分算法或者使用多种记分算法。关于记分算法,完全可以使用适配器模式。

那么这里的A、B、C类我应该抽象成接口还是抽象类呢?

 

   发表时间:2007-11-10  
你可以两种都试一下,再看看哪种比较爽一点
甚至你还可以先弄一个接口,然后为该接口弄一个基本的实现类,然后A、B、C再继承自该类......
0 请登录后投票
   发表时间:2007-11-10  
两种我都实现了,都可以实现,只是没弄明白设计上如何体现可扩展,抽象的层面。
如果实现接口
我可能会如此定义
public interface EquipmentAction {
   void modifyDegree(DegreeAdapter degreeAdapter);
}

然后用车床具体类来实现这个接口,如:
public class AEquipment implements EquipmentAction {
   private int degree;
   private long id;
   private Date lastRecordDate;
   private String equipmentName;
   private String equipmentCode;
   //通过对DegreeAdapter的强依赖来达到目的
   public void modifyDegree(DegreeAdapter degreeAdapter) {
      degree = degreeAdapter.parseDegree(degree, lastRecordDate);
   }
}

其实EquipmentAction接口的目的是提供了记分计算的算法,不同的设备来继承这个接口,达到可以用接口替换具体类的目的。这样做的目的是可以方便今后扩展记分方法。但不方便的地方是跟DegreeAdapter有太强的依赖,不能独立出来,似乎可测试性不好。请各位评价一下。

如果继承抽象类,其实也可以达到接口的目的,但或许我会这么写:
public abstract class Equipment {
   private int id;  //get,set方法省略
   private int degree;
   private Date lastRecordDate;
   public void modifyDegree(DegreeAdapter degreeAdapter) {
      degree = degreeAdapter.parseDegree(degree, lastRecordDate);
   }
}

这样写,我突然感觉到很别扭的感觉,不如用接口好。
抽象类应该怎么设计才比较合理呢?谢谢各位啦
0 请登录后投票
   发表时间:2007-11-11  
javalion 写道
两种我都实现了,都可以实现,只是没弄明白设计上如何体现可扩展,抽象的层面。
如果实现接口
我可能会如此定义
public interface EquipmentAction {
   void modifyDegree(DegreeAdapter degreeAdapter);
}

然后用车床具体类来实现这个接口,如:
public class AEquipment implements EquipmentAction {
   private int degree;
   private long id;
   private Date lastRecordDate;
   private String equipmentName;
   private String equipmentCode;
   //通过对DegreeAdapter的强依赖来达到目的
   public void modifyDegree(DegreeAdapter degreeAdapter) {
      degree = degreeAdapter.parseDegree(degree, lastRecordDate);
   }
}

其实EquipmentAction接口的目的是提供了记分计算的算法,不同的设备来继承这个接口,达到可以用接口替换具体类的目的。这样做的目的是可以方便今后扩展记分方法。但不方便的地方是跟DegreeAdapter有太强的依赖,不能独立出来,似乎可测试性不好。请各位评价一下。

如果继承抽象类,其实也可以达到接口的目的,但或许我会这么写:
public abstract class Equipment {
   private int id;  //get,set方法省略
   private int degree;
   private Date lastRecordDate;
   public void modifyDegree(DegreeAdapter degreeAdapter) {
      degree = degreeAdapter.parseDegree(degree, lastRecordDate);
   }
}

这样写,我突然感觉到很别扭的感觉,不如用接口好。
抽象类应该怎么设计才比较合理呢?谢谢各位啦
看了需求,俺记分原则似乎并不能分为三类啊。。
是不是a车床一定会隔两天才记分?B车床一定是不够一天就记分?

抽象类应该设计为所有子类所共有的东西,可以弥补子类在继承接口时要实现相同的功能的缺陷。

另外我觉得实现一个接口来达到不同的算法效果并不合适,这似乎应该用组合,也就是策略模式实现。。。
0 请登录后投票
   发表时间:2007-11-11  
eivenchan:嗯,你说的有道理。记分原则是根据上次记分时间和现在准备登记的时间差进行加分和减分操作的。只要在1天内进行登记就会加1分,其它则为减分。

抽象类应该抽象出共有的东西。嗯,没错,看来一下Spring的一些代码,总算是明白了一些东西。继续好好学习。也欢迎大家继续批判。
0 请登录后投票
   发表时间:2007-11-11  
javalion 写道
其实EquipmentAction接口的目的是提供了记分计算的算法,不同的设备来继承这个接口,达到可以用接口替换具体类的目的。这样做的目的是可以方便今后扩展记分方法。但不方便的地方是跟DegreeAdapter有太强的依赖,不能独立出来,似乎可测试性不好。请各位评价一下。

如果DegreeAdapter也是一个接口的话,你可以写一个mock类在测试时使用,这样可测试性可以提高一些吧?
0 请登录后投票
   发表时间:2007-11-14  
这两种方法是都可以实现你的需求,不过接口的优势在于一个类可以实现一个多个接口却只能继承一个类,所以如果你用抽象类来实现的话会大大的破坏它的扩展性。
0 请登录后投票
   发表时间:2007-11-14  
     那么这里的A、B、C类我应该抽象成接口还是抽象类呢?

abstract class和interface是Java语言中的两种定义抽象类的方式,它们之间有很大的相似性。但是对于它们的选择却又往往反映出对于问题领域中的概念本质的理解、对于设计意图的反映是否正确、合理,因为它们表现了概念间的不同的关系(虽然都能够实现需求的功能)。

我个人觉得可能用抽象类会比较合适点点.
0 请登录后投票
   发表时间:2007-11-15  
接口,他的修改性高。
抽象类,子类的代码少,修正方便可修改性差。
(不过选接口的话可以作工具类来减少代码数。)
我会用一个类+一个工具类来完成这个功能
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics