Java 与两种不同实现的接口

Java 与两种不同实现的接口,java,oop,inheritance,Java,Oop,Inheritance,我有一个接口Person,我有两个类Female和Male实现该接口 static void Main(Form form) { Person person = Factory.createPerson(form.getGender()); person.setName(form.getName()); if ("F".equals(gender)) { person.setPregnancyMonth(form.

我有一个接口
Person
,我有两个类
Female
Male
实现该接口

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

        if ("F".equals(gender)) {
            person.setPregnancyMonth(form.getPregnancyMonth());
        }
    }
对于女性类,我有一个男性类没有的方法
getPregnacyMonth
。将该方法添加到我的接口
Person
成为一个问题,因为我的
Male
类现在需要从接口继承该方法;但雄性永远不会怀孕

解决方案是什么?我是否需要
扩展
人员而不是
实施

编辑:如果我的问题不清楚,很抱歉。在本例中,我将
get
/
set
方法从
Male
memale
类添加到接口中

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

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

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

这听起来像是一个破碎的对象层次结构,但按照前面所述,您的接口需要两种方法:isFemale()和getpregnancemonth()。然后,Male.getPregnatureMonth()抛出一个不支持的操作异常。一个更好的方法可能是设计模型,这样男性就永远不会被置于一个需要询问其怀孕月份的位置。

在这里实现/扩展实际上并不重要。您可以让isPregnant()始终为男性返回false,也可以直接将该方法推入女性。鉴于您认为男性怀孕是荒谬的,您可以设计代码,使其只对女性调用isPregnant(),而不只是对任何人


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

在我看来,
getpregnancemonth
不够通用,不能出现在
person
界面中。它可能只应该在女性类中定义


您还可以定义第二个接口,其中包含
getpregnancemonth
。Female将实现这两个功能。

GetPregnacyMonth
不应出现在
Person
的界面中

就个人而言…没有双关语的意思…我认为你应该创建
Person
作为一个抽象类,因为女性和男性将共享许多相同的属性和功能


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

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

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

正如其他答案所建议的那样,尽可能避免这个问题。例如,您可以使用
instanceof
来检测给定的
人是
男性还是
女性
,并且仅当
人是
女性
时才调用
GetPregnitionMonth

编辑,回应评论:使用所描述的工厂方法在很大程度上是毫无意义的。如果我们忽略那些不希望被贴上“正常”性别标签的人,那么您只能创建一个
Male
Female
对象-您最好在
工厂中使用
public static Female createFemale()
public static Male createmeal()
方法。这样,你就可以避免所有这些麻烦了。它还将摆脱像枚举一样使用的字符串(即“男性”或“女性”作为
getPerson
的参数),但这是一个完全不同的问题

如果仍要使用组合工厂方法,则可以将结果强制转换为
女性

Female female = (Female) Factory.getPerson("female");
female.getPregnancyMonth ( );
或者,如果你的
可能是女性,也可能不是女性
,你也可以投下:

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

    female.getPregnancyMonth( );
}

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

应该没有必要将该方法移动到
Person
界面中。主要的技巧是,当执行
getPregnacityMonth()
时,必须确保处理的是
Female
实例,而不仅仅是
Person
实例

例如,如果您需要处理一组不需要任何特殊处理的
Person
对象,可以创建一个方法来轻松处理这些对象:

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

换言之,当您试图实现时,在更高的接口中尽可能保持抽象,但确保在需要时使用更具体的类型。使用一种技术,比如用一个更具体类型的
Person
创建一个单独的方法,可以在编译时避免获取
ClassCastException
,这非常好。

但是它不允许我编译,因为当Person-female=Factory.getPerson(“female”)时,方法female.getpregnancementmonth()将不存在,因为此人没有该方法,或者您也可以将女性和男性保留为具体类。请解决您的问题,这不是工厂模式问题,而是有关继承和oo设计的一般问题。+1将怀孕相关的内容放在一个专注于该行为的界面上