将向下转换的对象向上转换到原型缓冲区中 [英] Upcasting the downcasted object back in protobuffers

查看:100
本文介绍了将向下转换的对象向上转换到原型缓冲区中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是原始代码,

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

message Dog{
    optional string breed = 1;
}

然后使用上述原型

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!
    }

} 

仅通过在动物中将狗的实例设为必需",才能进行向上转换吗?还是还有其他上流方法?

解决方案

首先,要明确一点:向上转换"表示将Dog强制转换为Animal. 向下转换"表示将Animal强制转换为Dog.您的问题是关于如何向上转换的,但是您的示例似乎是关于向下转换的.我会尽力回答这两个问题.

我对您的其他问题的回答中,我提出了三种方法来模拟protobufs的继承.

选项1使向上转换很容易,但不允许向下转换.

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

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

社论:我知道这不是一个很令人满意的答案.协议缓冲区不能实现真正的继承,因为我们无法提出任何合理的设计.导线上向后和向前兼容的要求使此问题比看起来的复杂得多.但是在实践中,我们发现继承实际上实际上并不是您想要的,而我介绍的选项之一通常可以很好地工作.在我看来,继承对于接口(即具有行为的方法的集合)有意义,而对于消息(即包含简单数据的字段的集合)有意义.

Below is the proto code,

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

message Dog{
    optional string breed = 1;
}

Then the sample class using the above 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!
    }

} 

Is up-casting possible only by having an instance of dog as "required" in animal? or Is there any other way of upcasting?

解决方案

First, to be clear: "Upcasting" means casting a Dog to an Animal. "Downcasting" means casting an Animal to a Dog. Your question is about how to upcast, but your example appears to be about downcasting. I'll try to answer both.

In my answer to your other question, I presented three options for emulating inheritance with protobufs.

Option 1 makes upcasting easy but does not allow for downcasting.

Options 2 and 3 make downcasting possible, but do not support upcasting.

If you need to be able to both upcast and downcast, then you need to use option 2 or 3, but always pass around an Animal as simply an Animal. That is, if you have a function which only works on Dog, but needs to access some of the members of Animal as well, it must take Animal as its argument. The function's documentation should state that even though the argument type is Animal, the argument must have the dog field (or extension) set, i.e. it must actually be a Dog. You should throw an IllegalArgumentException otherwise.

Editorial: I know this is not a very satisfying answer. Protocol Buffers does not implement true inheritance because we couldn't come up with any design that seemed reasonable. The requirements of backwards- and forwards-compatibility on the wire make this problem a lot more complicated than it may seem. In practice, though, we've found that inheritance is rarely actually what you want anyway, and one of the options I presented usually works fine. In my opinion, inheritance makes sense for interfaces (i.e. collections of methods with behavior), but not for messages (i.e. collections of fields containing simple data).

这篇关于将向下转换的对象向上转换到原型缓冲区中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆