【Solidity】継承における菱形継承問題とC3 linearizationについて
本日は、下のエラーコードを元に、継承におけるC3 linearizationについて見ていきたいと思います。
TypeError: Linearization of inheritance graph impossible
1 日本語にすると?
継承グラフの線形化が不可能
⇨継承グラフの線形化が不可能となっているので、具体的にはどのような問題なのでしょう。
2 Diamond Problem(菱形継承問題)とは
こちらのStackExchangeを元に見ていきましょう。
まず、これは「Diamond Problem」と言われます。
では「Diamond Problem」とはなんでしょう。
Wikipediaを見てみましょう。
下のように継承が行われているとき、BとCそれぞれでオーバーライドが行われています。
そんな時、Aはどちらを呼び出せば良いの?というのがDiamond Problem(菱形継承問題)です。
3 C3 Linearizationとは
Solidityは「C3 linearization」を用いているようですが、これはなんでしょう。
こちらの記事が非常にわかりやすかったです。
C3のCは「Condition(条件)」であり、3つの条件を満たす必要があるようです。
では、具体的に見ていきましょう。
(ざっくりとした説明なので、詳細はshinsa82さんの記事をご確認ください。)
3ー0 継承関係による制約
まずは、前提です。
探す順番は「子クラス⇨親クラス」の順番となります。
3ー1 ローカル優先度による制約
まずは、線形化は書かれている順番で行われます。
例えばE( A , D )となっているので「A⇨D」の順番で線形化されます。
3ー2 単調性
単調性は拡張の順番が矛盾しないようにします。
例えば下のように、A( B , C )となっている場合、AはBおよびCをまず線形化します。
右のように、Bの後にDを線形化してしまうと、Cの線形化前に行われてしまうこととなり、単調性を満たしません。
3ー3 拡張優先度グラフとの整合性
最後は整合性による、制約の追加についてです。
下のDとEには明示的な制約はありません。
しかしA( B , C )となっている場合、この優先度を伝播させて、D⇨Eの制約が追加されます。
4 SolidityのHPでも見てみよう
SolidityのHPでも見てみましょう。
継承時には順番が大事であり
とされています。
また、コンストラクタの記載について注意があります。
具体的には継承の順番とコンストラクタの順番が異なるときはどちらを優先させるかという問題です。
その場合、下のように、継承の順番を優先させることが書いてあります。
今回は以上です。