我正在尝试设计接口和类来解析pcap格式文件中的某些类型的数据包。 (我知道存在特殊的库,但我需要自己做)
所以我有一个分类器接口,该方法会检查它是否是一个有效的数据包。
public interface Classifier {
boolean classify (PcapPacket pcapPacket);
}
解析器接口的方法会将PcapPacket
内的字节数组转换为某些字段。 P
代表新的解析数据包,S
代表统计数据。
public interface Parser<P, S> extends Classifier {
P parsePacket (PcapPacket pcapPacket);
P parsePacket (PcapPacket pcapPacket, P outPacket);
S parseReader (PcapReader pcapReader);
}
现在我已经实现了AParser
,它可以解析某个数据包或文件。
public class AParser implements Parser<APacket, AStats>, Classifier {
但考虑到BParser
,我现在很难在AParser
的顶部实施BPacket extends APacket
。
public class BParser extends AParser implements Parser<BPacket, BStats> {
在parsePacket
我想做这样的事情:
BPacket parsePacket (PcapPacket pcapPacket) {
APacket apacket = super.parse(pcapPacket);
BPacket bpacket = new BPacket(apacket);
//extract val1 and val2 from pcapPacket
bpacket.set(val1, val2);
return bpacket;
}
粗体显示编译错误。在这一点上,我理解我的方法有问题。可能,我在定义接口时需要使用泛型。
您如何帮助我重新设计此代码以使其在未来更加灵活?
答案 0 :(得分:1)
是的,泛型和子类不能很好地一起玩。您已经声明了解析器(AParser)的特化,它将其泛型参数绑定到给定对象(APacket)。然后,您不能使用一组不同的泛型参数从此专门化扩展。就像你试图这样做:
public class BParser implements Parser<APacket, AStats>, Parser<BPacket, BStats> {
哪个不起作用,因为类型擦除意味着你有一堆方法转换为相同的签名。一个更可行的解决方案是将专用解析器的通用功能推送到一个抽象基类,该基类使不将通用参数绑定到特定类型。用伪代码说明:
public abstract class BaseParser<P, S> implements Parser<P, S> {
// common functionality here
}
public class AParser extends BaseParser<APacket, AStats> {
// functionality specific to AParser
}
public class BParser extends BaseParser<BPacket, BStats> {
// functionality specific to BParser
}