63

如何处理 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;
}
4

2 回答 2

83

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

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

然而,话虽如此,你可以使用一个类似于继承的技巧——但这是一个丑陋的 hack,所以你应该小心使用它。如果您定义消息类型,例如:

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

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

您可以使用它来实现类似继承之类的东西,方法是让几种类型都包含“超类”字段的副本。但是,这种方法存在几个大问题:

  • 要将 type 的消息对象转换Foo为 type Bar,您必须序列化和重新解析;你不能只投。这可能是低效的。
  • 向超类添加新字段非常困难,因为您必须确保将字段添加到每个子类,并且必须确保这不会造成任何字段编号冲突。
于 2016-12-21T05:50:57.483 回答
37

请参阅协议缓冲区基础教程:

不过,不要去寻找类似于类继承的工具——协议缓冲区不会那样做。

于 2016-12-20T13:22:00.720 回答