見出し画像

【Solidity】継承における菱形継承問題とC3 linearizationについて

本日は、下のエラーコードを元に、継承におけるC3 linearizationについて見ていきたいと思います。

TypeError: Linearization of inheritance graph impossible

1 日本語にすると?

継承グラフの線形化が不可能

継承グラフの線形化が不可能となっているので、具体的にはどのような問題なのでしょう。

2 Diamond Problem(菱形継承問題)とは

こちらのStackExchangeを元に見ていきましょう。

まず、これは「Diamond Problem」と言われます。

では「Diamond Problem」とはなんでしょう。

Wikipediaを見てみましょう。

下のように継承が行われているとき、BとCそれぞれでオーバーライドが行われています。

https://ja.wikipedia.org/wiki/%E8%8F%B1%E5%BD%A2%E7%B6%99%E6%89%BF%E5%95%8F%E9%A1%8C

そんな時、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でも見てみましょう。

継承時には順番が大事であり

① 基本 ⇨ 派生 の順番で書いていく
② 検索は右から左に行われる

とされています。

また、コンストラクタの記載について注意があります。

具体的には継承の順番とコンストラクタの順番が異なるときはどちらを優先させるかという問題です。

その場合、下のように、継承の順番を優先させることが書いてあります。


今回は以上です。

いいなと思ったら応援しよう!

ユウキ
サポートをしていただけたらすごく嬉しいです😄 いただけたサポートを励みに、これからもコツコツ頑張っていきます😊