协议缓冲区中的继承

时间:2016-12-20 13:11:00

标签: java protocol-buffers protocol-buffers-3

如何处理Google Protocol Buffers 3.0中的继承?

Java等效代码:

public class Bar {
    String name;
}
public class Foo extends Bar {
    String id;
}

什么是Proto等效代码?

message Bar {
    string name = 1;
}
message Foo {
    string id = 2;
}

2 个答案:

答案 0 :(得分:24)

协议缓冲区不支持继承。相反,请考虑使用组合:

message Foo {
  Bar bar = 1;
  string id = 2;
}

然而,那说,有一个你可以使用的技巧,就像继承 - 但这是一个丑陋的黑客,所以你应该只小心使用它。如果您定义了以下消息类型:

message Bar {
  string name = 1;
}
message Foo {
  string name = 1;
  string id = 2;
}

这两种类型兼容,因为Foo包含Bar字段的超集。这意味着如果您有一种类型的编码消息,则可以将其解码为另一种类型。如果您尝试将Bar解码为Foo类型,则不会设置字段id(并将获得其默认值)。如果您将Foo解码为Bar类型,则会忽略字段id。 (请注意,这些规则与在一段时间内向类型添加新字段时适用的规则相同。)

你可以使用它来实现类似继承的东西,通过使用几种类型,所有类型都包含"超类"的字段的副本。但是,这种方法存在一些大问题:

  • 要将Foo类型的消息对象转换为类型Bar,您必须序列化并重新解析;你不能演员。这可能效率低下。
  • 向超类添加新字段非常困难,因为您必须确保将字段添加到每个子类,并且必须确保这不会创建任何字段编号冲突。< / LI>

答案 1 :(得分:13)

请参阅Protocol Buffer Basics教程:

  

不要寻找类似于类继承的设施,但协议缓冲区不会这样做。