我有一个超类,让我们说 BaseClass 和两个子类,比方说 SubclassA 和 SubclassB ,他们没有任何其他关系他们之间,但他们的父母班。
在我的代码中的很多地方,我需要调用子类都有但不是父类的方法......我发现自己重复了很多看起来像的代码:
if (obj instanceof SubclassA) {
// stuff
} else if (obj instanceof SubclassB) {
// same stuff
}
第一个想法应该是将“stuff”放入超类中的方法中,但我不能因为超类是其他没有该行为的子类的父类...
那么......有没有办法避免重复该代码的aaaalll?
可能是两个子类的公共超类,它们是超类的子类本身吗?
答案 0 :(得分:5)
我建议在父类中提取方法作为抽象方法(如果父类是抽象的),或者只是在子类中重写的方法。如果这是不可能的,或者我希望我建议添加一个扩展父类的公共抽象类,它只包含两个子类共有的方法,然后由两个子类扩展。
如果添加和更改父类可能是个问题,你可以通过使用一个接口来做同样的事情,然后由两个子类实现,你需要调用你的代码,你只需要转换到给定的接口并调用需要的方法。
这样的事情:
interface CommonInterface {
void commonMethod();
}
class SubClassB implements CommonInterface {
void commonMethod() {
// implementation
}
}
class SubClassA implements CommonInterface {
void commonMethod() {
// implementation
}
}
//...
if (obj instanceof CommonInterface) {
((CommonInterface)object).stuffCall();
}
答案 1 :(得分:2)
将方法添加到超类中
用空体做成。
在SubClassA中覆盖它,实现你需要的逻辑
在SubClassB中覆盖它,实现你需要的逻辑。
然后在你的调用代码中,而不是做
if (obj instanceof SubclassA) {
obj.method();
} else if (obj instanceof SubclassB) {
obj.method();
}
就这样做
obj.method();
提供obj
被声明为父类的实例。
超类中的空方法体保证你有
没有这个的问题“但我不能因为超级班是父母
到其他没有这种行为的子类“。
所以这个想法就是你会有空洞的行为
在超类和所有子类中
不要明确覆盖此方法。
答案 2 :(得分:1)
以下两种方式如何:
答案 3 :(得分:1)
如果SubClassA和SubClassB有一些不存在于子类C,D,E等中的行为,那么只需在父和A和B之间引入一个中间类.C,D等从父类派生,而B从新派生而来class,包含A和B共享的功能。
答案 4 :(得分:1)
首先,多态的概念是在调用对象的方法之前不需要检查对象的类型。因此,在OO语言中这不是必需的。
其次,您可能在接口上使用抽象父类的原因是因为子类型(子类)之间存在一些共享功能。因此,如果SubclassA
和SubclassB
之间存在共享的常用功能,则保留您的超类完整,否则将其切换到接口。
同样地,正如您自己建议的那样,如果SubclassA
和SubclassB
有共同的行为(但是他们自己的实现),那么请使用单独的API(如果BaseClass
的其他子类型不要也分享这种行为(你的#doStuff
电话)。
在这种情况下,我将介绍包含方法Stuff
的接口#doStuff
,并让我的SubclassA
和SubclassB
实现它,每个都提供它自己的实现。然后,您的客户可以将obj
实例视为Stuff
,无论其真实类型如何,多态性都将完成。
interface Stuff {
void doStuff();
}
public class SubclassA extends BaseClass implements Stuff {
// Does it need BaseClass still?
public doStuff() {
...
}
}
public class SubclassB extends BaseClass implements Stuff {
// Does it need BaseClass still?
public doStuff() {
...
}
}
// Example client code...
public class MyStuffClient {
Stuff s = new SubclassA();
...
public void onStuff() {
s.doStuff();
}
}
决定你是否真的需要上级BaseClass
。
答案 5 :(得分:0)
您可以在超类protected
上创建该方法。例如,您可以在 SuperClass :
package test;
public SuperClass {
protected void myMethod() {
...stuff...
}
}
公开 SubclassA
package test;
public SubclassA extends SuperClass {
public void myMethod() {
super.myMethod();
}
}
并隐藏在 SubclassB (只是不覆盖它)
package test;
public SubclassB extends SuperClass {
}
从其他软件包,受保护的方法不可见,除非该类覆盖它更改其可见性修饰符。
来源:http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html