如何正确组织我的类/继承/实现?

时间:2014-02-23 16:42:32

标签: java interface implements

我目前正在开展一个学校项目。在这个项目中,我们应该首先从医生的角度看待世界的模型,包括他的病人,不同的药物(有搽剂,药丸和注射剂等界面),药物处方和容器处方和人。

这就是作业的第一部分所说的: 药品有名称,唯一编号和价格。药物类型为A型(麻醉剂,其中相关的int代表药物的麻醉/效力),B型(强烈上瘾,相关的int代表药物的成瘾程度)或C型(“正常”不含联想性药物)其他两种类型都有)。

类型A,B和C应该被实现为接口。我的问题是我应该构建类的方式; 我强烈反对这是组织课程的最佳方式,但在研究不同的方法后,我发现自己对 最佳实现的内容感到困惑。

我想做这样的事情。药物可以是一个抽象类,有3个具体的子类:

                               PharmaceuticalDrug

                            /           |           \

                       Liniment        Pill       Injection

我的问题是如何实现类型A,类型B和类型C ,因为与这些类型关联的实例变量。 类型A和B需要额外的实例变量来表示它们的“效力”,而C不需要。我可以简单地包含实例变量并将类型C的实例变量设置为非功能值(如-1)以指示不使用该值,但这种方法对我来说似乎不是一个很好的解决方案,因为我我将稍后将所有信息的处方写入文件,并希望通过简单的方法循环执行此操作,而无需进行不必要的测试和C类特殊情况。

我试过想出几种方法来解决这个问题。教师们声明我们可以使用Type A,B和C作为接口并相应地实现它们,但据我所知,我不能实现一个接口,具体取决于它是这种类型还是实现另一个接口,如果它是另一种。我读到了动态代理,但它似乎并不完全相同。也许我错了。如果是这样,我为我的无知而道歉。

在这种情况下,我会喜欢这样做: (注意:我知道这不是工作/实际代码,实现应该在类的名称和药物继承之后,但它只是为了说明我想做什么)。

    public class Liniment extends PharmaceuticalDrug {
        ...

        public Liniment( String type ) {
            if ( type.equals( "A" ) ) {
                // make this class implement type A
            } else if ( type.equals( "B" ) {
                // make this class implement type B
            } else if ( type.equals( "C" ) { // type C
                // make this class implement type C **WITHOUT INSTANCE VARIABLE!**
            } else {
                System.out.println( "Error!" );
            }
        }

        ...
    }

我认为可行的另一种方法是制作A,B和C类型的枚举。但是,我仍然不知道如何处理类型C所需的实例变量。我只希望实例变量与类型A和B相关联,因为类型C应该没有额外的功能/实例变量。 / p>

我认为我能做到的最后一种方式:制作Liniment,Pill和Injection的子类,I.E。 LinimentTypeA,LinimentTypeB,LinimentTypeC,PillTypeA,...,InjectionTypeC。虽然这很有效,但这看起来很丑陋,会产生大量重复的代码,让我觉得我的问题有一个更简单的解决方案。

我希望能够实现A,B或C类型,具体取决于它是哪种药物如果类型是A或B,则添加/拥有一个额外的实例变量,但如果药物属于C类,则不是

关于如何最好地解决这个问题的任何想法?

3 个答案:

答案 0 :(得分:1)

  

我可以简单地包含实例变量并设置类型C的实例   变量为非功能值(如-1)

这确实是一种糟糕的方式。只是以“逻辑”的方式做到这一点。继承是“是一种”关系。 A,B和C型是药物。所以它们确实是Drug的子类。 A和B确实有一个额外的int属性。最好将属性命名为不同的类型:类型A为int potency,类型B为int addictivity

  

教师们表示我们可以使用A,B和C类型   接口并相应地实现它们

这意味着Drug是超级界面。 TypeA,TypeB和TypeC也是扩展 Drug的接口。 相应地实现它们意味着您必须创建至少一个实现每个Type的具体类。

接口应包含必要属性的getter。

使用接口的一个优点是您可以从Java继承多个接口。因此,您可以实现具体的类:public class Marjuana implements TypeA, TypeB

答案 1 :(得分:1)

对于您的药物类型问题,您可以这样做:

  • 包含所有常用方法的药物的通用界面
  • 具有该效力的A和B类型的上述接口的扩展,带有一些getPotency() - 类似的方法
  • 然后你可以创建A和B类型作为上面的扩展,而C作为通用接口的扩展
  • 之后,您的具体药物实施将能够实施多种药物类型

然后,对于具体的LinimentTypeA等,您可以尝试实现工厂模式,它会根据您的类型吐出Liniment类的不同扩展的实例(例如)。一个例子:

class DrugFactory {
  public Liniment getLinimentInstance(String type) {
    switch (type) {
    case "A": return new Liniment() { // your overrides and other stuff here } ;
    // etc
    default: return null;
  }

  public Pill getPillInstance(String type) {
    // similar
  }

  // other stuff you might want
}

答案 2 :(得分:0)

您可以考虑:

  1. 将药效变量添加到药物的超类
  2. 定义三个接口(TypeA,TypeB,TypeC)
  3. 定义Liniment,Pill,Injection的接口
  4. 然后创建PharmaceuticalDrug的子类,如:TypeALiniment,TypeBLiniment,TypeCLimiment等。
  5. 您使用public class TypeALiniment extends PharmaceutialDrug implements TypeA, Liniment {xxx}

    的地方