繁体   English   中英

与两种不同实现的接口

[英]Interface with two different implementations

我有一个Person接口,我有 2 个实现该接口的类FemaleMale

对于女性 class,我有一个方法getPregnancyMonth ,而我的男性 class 没有。 将该方法添加到我的接口Person成为一个问题,因为我的Male class 现在需要从接口继承该方法; 但男性永远不会怀孕。

什么是解决方案,我是否需要extend Person 而不是implement

编辑:对不起,如果我的问题不清楚。 在这种情况下,我已将MaleFemale类的get / set方法添加到接口中。

    static void Main(Form form) {
        Person person = Factory.createPerson(form.getGender());
        person.setName(form.getName());

        if ("F".equals(gender)) {
            person.setPregnancyMonth(form.getPregnancyMonth());
        }
    }

我的问题是,由于我的接口有getPregnancyMonth ,我的男性必须将该方法添加到具体的 class 以实现接口。 有没有办法避免这种情况?

getPregnancyMonth不应该在Person的接口中。

就个人而言...没有双关语...我认为您应该将Person创建为抽象 class ,因为女性和男性将共享许多相同的属性和功能。

然后,您可以创建反映每种性别的独特功能的女性和男性界面。

不需要将该方法移到Person接口中。 主要技巧是,当执行getPregnancyMonth()时,您必须确保处理的是Female实例,而不仅仅是Person实例。

例如,如果您需要处理一堆不需要任何特殊处理的Person对象,可以创建一个方法来轻松完成此操作:

public static void processPeople(List<Person> people) {
    for (Person p : people) {
        p.someMethod();
    }
}

但是,当您必须处理getPregenancyMonth()方法时,您必须确保您的方法只接受Female实例:

public static void checkBirthSchedule(Female girl) {
    girl.getPregnancyMonth();
    ...
}

换句话说,正如您试图理解的那样,在更高的接口中尽可能保持抽象,但在需要时确保您使用更具体的类型。 使用一种技术,例如使用更具体的Person类型创建一个单独的方法,可以在编译时节省您获取ClassCastException的时间,这非常好。

在我看来, getPregnancyMonth不够通用,不能放在Person接口中。 它可能应该只在女性 class 中定义。

您还可以定义包含该getPregnancyMonth的第二个接口。 女性将同时实施。

实施/扩展在这里并不重要。 您可以让 isPregnant() 始终为男性返回 false,或者您可以直接将该方法推送到女性中。 看到您认为男性怀孕是荒谬的,您将设计您的代码,使其仅在女性上调用 isPregnant(),而不仅仅是对任何人。

顺便说一句,我并不是说加入 if(person instanceof Female),设计你的 heiarchy 以避免这种情况。

不要将getPregnancyMonth添加到Person 正如您所发现的,这没有多大意义。

在面向 object 的编程中,基类/接口应该(理想情况下)只包含其每个子类共有的细节 - 因为getPregnancyMonth对两个子类都不共有(它对Male没有任何意义),它应该'不在Person界面中。 我再次强调——这是在谈论理想。

正如其他答案所建议的那样,如果可以的话,尽量避免这个问题。 例如,您可以使用instanceof来检测给定的PersonMale还是Female ,并且只有在PersonFemale时才调用getPregnancyMonth

编辑,回应评论:使用所描述的工厂方法在很大程度上是没有意义的。 如果我们忽略那些不希望被标记为“正常”性别的人,那么您将只会创建MaleFemale object - 拥有public static Female createFemale ( )public static Male createMale ( ) Factory中的public static Male createMale ( )方法。 这样,您将避免所有这些麻烦。 它还将摆脱像枚举一样使用的字符串(即“男性”或“女性”作为getPerson的参数),但这是完全不同的事情......

如果您仍想使用组合工厂方法,您可以将结果转换为Female

Female female = (Female) Factory.getPerson("female");
female.getPregnancyMonth ( );

或者,如果您有一个Person可能是也可能不是Female ,您也可以使用它:

if (person instanceof Female)
{
    Female female = (Female) person;

    female.getPregnancyMonth( );
}

我不能说我过分喜欢这两种方法中的任何一种——它们都有自己的位置,但通常有更好的方法。

这听起来像是一个损坏的 object 层次结构,但按照说明,您的界面需要两个方法:isFemale() 和 getPregnancyMonth()。 然后 Male.getPregnancyMonth() 抛出 UnsupportedOperationException。 更好的方法可能是设计您的 model 以便男性永远不会被放入 position 中,在那里会询问他的怀孕月份。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM