0

以下はプロトコードです。

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

} 

動物で「必須」として犬のインスタンスを持つことによってのみ、アップキャストは可能ですか? またはアップキャストの他の方法はありますか?

4

1 に答える 1

1

まず、明確にするために、「アップキャスト」とは、 aDogを an にキャストすることを意味しAnimalます。「ダウンキャスト」とは、 を にキャストするAnimalことを意味しDogます。あなたの質問はアップキャストの方法に関するものですが、あなたの例はダウンキャストに関するものです。両方答えてみます。

の質問への回答で、protobufs を使用して継承をエミュレートするための 3 つのオプションを提示しました。

オプション 1 では、アップキャストは簡単ですが、ダウンキャストはできません。

オプション 2 と 3 はダウンキャストを可能にしますが、アップキャストはサポートしません。

アップキャストとダウンキャストの両方を可能にする必要がある場合は、オプション 2 または 3 を使用する必要がありますが、常に をAnimal単に として渡しAnimalます。つまり、 でのみ機能Dogするが、 のメンバーの一部にもアクセスする必要がある関数がある場合、引数としてAnimal取る必要があります。Animal関数のドキュメントには、引数の型が であっても、引数Animalにはdogフィールド (または拡張子) が設定されている必要がある、つまり実際には である必要があると記載されている必要がありますDog。そうでなければスローする必要がありIllegalArgumentExceptionます。

社説: これが満足のいく答えではないことは承知しています。Protocol Buffers は真の継承を実装していません。妥当と思われる設計を思いつくことができなかったからです。ネットワーク上での後方互換性と前方互換性の要件により、この問題は見かけよりもはるかに複雑になります。ただし、実際には、継承が実際に必要なものになることはめったになく、提示したオプションの 1 つで通常は問題なく動作することがわかりました。私の意見では、継承はインターフェイス (つまり、動作を伴うメソッドのコレクション) には意味がありますが、メッセージ (つまり、単純なデータを含むフィールドのコレクション) には意味がありません。

于 2014-02-02T04:17:09.707 に答える