0

下面是原型代码,

message Animal {
    optional string name = 1;
    optional int32 age = 2;  
}    

message Dog{
    optional string breed = 1;
}

然后是使用上述proto的示例类

public class InheritanceTest {

    public static void main(String[] args){
        Dog dog = Dog.getDefaultInstance();
        printAnimalName(dog.getAnimal());
    }

    public static void printAnimal(Animal animal){
        Dog dog = (Dog)animal; // Not at all possible right!
    }

} 

只有通过在动物中将狗作为“必需”的实例才能进行向上转换吗?或者还有其他向上转换的方式吗?

4

1 回答 1

1

首先,要明确:“向上转换”意味着将 aDog转换为Animal. “向下转换”意味着将 anAnimal转换为Dog. 您的问题是关于如何向上转换,但您的示例似乎是关于向下转换。我会尽力回答这两个问题。

我对您的另一个问题的回答中,我提出了三个使用 protobuf 模拟继承的选项。

选项 1 使向上转换变得容易,但不允许向下转换。

选项 2 和 3 使向下转换成为可能,但不支持向上转换。

如果您需要同时进行向上转换和向下转换,则需要使用选项 2 或 3,但始终将 aAnimal简单地传递为Animal. 也就是说,如果您有一个适用于的函数Dog,但还需要访问其中的一些成员Animal,则它必须Animal作为其参数。函数的文档应该说明即使参数类型是Animal,参数也必须设置dog字段(或扩展名),即它实际上必须是Dog. 你应该抛出一个IllegalArgumentException否则。

社论:我知道这不是一个非常令人满意的答案。Protocol Buffers 没有实现真正的继承,因为我们想不出任何看起来合理的设计。对线路向后和向前兼容的要求使这个问题比看起来要复杂得多。但是,在实践中,我们发现继承很少是您真正想要的,而我提出的其中一个选项通常可以正常工作。在我看来,继承对于接口(即具有行为的方法的集合)是有意义的,但对于消息(即包含简单数据的字段的集合)则不是。

于 2014-02-02T04:17:09.707 回答