具有两种不同实现的接口

时间:2011-08-16 02:42:35

标签: java oop inheritance

我有一个接口Person,我有2个类FemaleMale来实现接口。

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

什么是解决方案,我需要extend人而不是implement吗?

编辑:对不起,如果我的问题不明确。在这种情况下,我已将getset类中的Male / Female方法添加到界面中。

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

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

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

6 个答案:

答案 0 :(得分:5)

getPregnancyMonth不应位于Person的界面中。

个人......没有双关语...我认为你应该创建Person作为抽象类,因为女性和男性将分享许多相同的属性和功能。

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

答案 1 :(得分:3)

不需要将该方法移动到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,这非常好。

答案 2 :(得分:2)

在我看来,getPregnancyMonth不够通用,无法进入Person界面。它应该只在女性班级定义。

您还可以定义包含getPregnancyMonth的第二个界面。女性将实施两者。

答案 3 :(得分:1)

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

顺便说一下,我并不是指扔一个if(女性的女性),设计你的heiarchy以避免这种情况。

答案 4 :(得分:1)

请勿将getPregnancyMonth添加到Person。正如你所发现的,这没有多大意义。

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

正如其他答案所暗示的那样,如果可以的话,尽量完全避免这个问题。例如,您可以使用instanceof来检测给定的PersonMale还是Female,如果getPregnancyMonth则只调用PersonFemale

编辑,以回应评论:使用所描述的工厂方法基本上没有意义。如果我们忽略了那些不希望被标记为“正常”性别的人,那么您只会创建一个MaleFemale对象 - 您只需拥有{{{您public static Female createFemale ( )中的1}}和public static Male createMale ( )方法。通过这种方式,您可以避免所有这种麻烦。它也会像enum一样摆脱使用的字符串(即“男性”或“女性”作为Factory的参数),但这是完全不同的事情......

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

Female

或者,如果您的Female female = (Female) Factory.getPerson("female"); female.getPregnancyMonth ( ); 可能是Person,也可能不是Female,那么您也可以投出:

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

    female.getPregnancyMonth( );
}

我不能说我过于喜欢这两种方法 - 他们有自己的位置,但通常有更好的方法。

答案 5 :(得分:0)

这听起来像是一个破碎的对象层次结构,但如上所述,您的界面需要两种方法:isFemale()和getPregnancyMonth()。然后Male.getPregnancyMonth()抛出UnsupportedOperationException。一个更好的方法可能是设计你的模型,这样男性就永远不会被置于怀孕月份的位置。