So imagine we have a base class Message:
public abstract Class Message {
Object content;
public Message(Object content) {
this.content = content;
}
}
And various implementations:
public Class Packet extends Message {
public Packet(Long largeNumber) {
super(largeNumber);
}
public Long unpack() {
return (Long) content;
}
}
public Class Letter extends Message {
public Letter(Short smallNumber) {
super(smallNumber);
}
public Short unpack() {
return (Short) content;
}
}
Now suppose we have a sender class, that sends the Messages somewhere.
public Class Sender {
public send(Message msg) {
// send it somewhere
}
}
And a receiver class, that receives the Message:
public Class Receiver {
receive(Message msg) {
// do something with the msg
}
}
The receiver class however just gets the Super class Message and doesn't know beforehand, which subclass it will receive. So how would I now "unpack" the message?
If we assume that I knew exactly what message would land where, I could use downcasting like this:
Packet packet = (Packet) msg;
But somehow this feels wrong as it kind of dismisses the point of polymorphism to begin with. Would it be better to just send the absolute sub-messages? Or is there a solution to such a problem I don't see (e.g. using Generics in some variation - I'm not too familiar with them)?
Unpacking the message can be done by the message itself, using the visitor pattern:
public abstract Class Message {
void send(Receiver r) {
r.receive(this); // Catch-all
}
}
public Class Packet extends Message {
void send(Receiver r) {
r.receive(this); // Overload for packets
}
}
public Class Letter extends Message {
void send(Receiver r) {
r.receive(this); // Overload for letters
}
}
public Class Receiver {
// There is an overload for each subclass
receive(Packet packet) {
}
receive(Letter letter) {
}
// This is the catch-all implementation
receive(Message msg) {
}
}
This approach lets receiver process letters and packets separately, in a statically-typed context. Catch-all implementation is often used for error reporting.