![](/img/trans.png)
[英]Two implementations for an interface with different types - Is this not possible?
[英]Interface with two different implementations
我有一个Person
接口,我有 2 个实现该接口的类Female
和Male
。
对于女性 class,我有一个方法getPregnancyMonth
,而我的男性 class 没有。 将该方法添加到我的接口Person
成为一个问题,因为我的Male
class 现在需要从接口继承该方法; 但男性永远不会怀孕。
什么是解决方案,我是否需要extend
Person 而不是implement
?
编辑:对不起,如果我的问题不清楚。 在这种情况下,我已将Male
和Female
类的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
来检测给定的Person
是Male
还是Female
,并且只有在Person
是Female
时才调用getPregnancyMonth
。
编辑,回应评论:使用所描述的工厂方法在很大程度上是没有意义的。 如果我们忽略那些不希望被标记为“正常”性别的人,那么您将只会创建Male
或Female
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.