我正在研究polmorphism和面向接口的设计,我遇到的问题是让我的类根据收到的对象执行正确的方法,以避免使用insntanceOf或类型转换。
我创建了一个代表Envelope(文本包装器)集合的接口,在这个接口中我有这个方法:
Interface Envelopes{
public void add(Envelope envelope);
}
我的目的是在每个实现中覆盖此方法,以允许每个实现使用特定类型来访问包络数据。例如,我在我的类EnvelopesWithColor(它存储带有颜色信息的信封)中以这种方式实现它:
Interface EnvelopesWithColor extends Envelope{
public void add(EnvelopeWithColor envelope) {
System.out.println("ADDING ENVELOPE WITH COLOR" + envelope.getClass());
}
@Override
public void add(Envelope envelope) {
System.out.println("ADDING ENVELOPE " + envelope.getClass());
}
}
到目前为止,这么好。为了避免耦合我想要声明一个Envelopes对象,并开始向它添加包络,例如。
Envelopes envelopes = new EnvelopesWithColor();
envelopes.add(new SimpleEnvelope("some text"));
envelopes.add(new SimpleEnvelopeWithColor(new SimpleEnvelope("some text with color"));
问题是:如果我使用Interface类型实例化Envelope,它就没有意识到传递的是什么类型的对象,只是在我提供EnvelopeWithColor时执行add(信封信封),打印结果如下: / p>
ADDING ENVELOPE class SimpleEnvelope
ADDING ENVELOPE class SimpleEnvelopeWithColor
另一方面,如果我直接实例化我的信封类型......
new EnvelopesWithColor().add(new SimpleEnvelope("some text"));
new EnvelopesWithColor().add(new SimpleEnvelopeWithColor(new SimpleEnvelope("some text with color"));
我有这个输出:
ADDING ENVELOPE class SimpleEnvelope
ADDING ENVELOPE WITH COLOR class SimpleEnvelopeWithColor
定义实现Envelopes类型也会输出正确的结果:
EnvelopesWithColor envelopes = new EnvelopesWithColor();
envelopes.add(new SimpleEnvelope("some text"));
envelopes.add(new SimpleEnvelopeWithColor(new SimpleEnvelope("some text with color"));
结果:
ADDING ENVELOPE class SimpleEnvelope
ADDING ENVELOPE WITH COLOR class SimpleEnvelopeWithColor
有一些(优雅的)方法可以发现Envelopes接口的哪些实现被发送到我的add()方法(优雅我的意思是不使用instanceof / typecasting)?我已经尝试了很多方法,使用泛型子类型,泛型方法,包装器方法,并没有成功。为什么实现没有收到实际的对象?
答案 0 :(得分:1)
你的多态性错误。
多态性只是关于调用方法的对象。
参数类型在多态性中不起作用。换句话说:多态与重载不同! (在更狭隘的Java意义上 - 正如文斯很好地指出的那样,概念上重载可以被视为“ad hoc多态”)。
从这个意义上说:使用Java,您需要 instanceof 检查 - 或者您必须改变逻辑。您没有在Envelopes类上进行重载,而是在Envelope类上使用多态方法。然后彩色信封对象表现不同。
答案 1 :(得分:1)
正如GhostCat所说,你得到了错误的方法。 你这样做:
class Envelopes {
public void add(Envelope env) {
System.out.println("adding" + env.getDescription());
}
}
interface Envelope {
String getDescription() ;
}
class NormalEnvelope implements Envelope {
public String getDescription () {
return "envelope" ;
}}
class EnvelopeWithColor implements Envelope {
public String getDescription () {
return "envelope with color" ;
}}
问题是,你这样做的方法是编译器解析调用哪个方法,而不是运行时。