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将怀孕相关的内容放在一个专注于该行为的界面上