我有一个接口Person
,我有2个类Female
和Male
来实现接口。
对于女班,我有一个方法getPregnancyMonth
,我的男班没有。将该方法添加到我的接口Person
会成为一个问题,因为我的Male
类现在需要从接口继承该方法;但男性永远不会怀孕。
什么是解决方案,我需要extend
人而不是implement
吗?
get
和set
类中的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
,我的男性必须将该方法添加到具体类中以实现接口。有没有办法避免这种情况?
答案 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
来检测给定的Person
是Male
还是Female
,如果getPregnancyMonth
则只调用Person
是Female
。
编辑,以回应评论:使用所描述的工厂方法基本上没有意义。如果我们忽略了那些不希望被标记为“正常”性别的人,那么您只会创建一个Male
或Female
对象 - 您只需拥有{{{您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。一个更好的方法可能是设计你的模型,这样男性就永远不会被置于怀孕月份的位置。