「継承した定義 ***(名前空間 public)にコンフリクトが存在します」理由

FlashProfessionalプロジェクトとして、AS3プログラミングをしていると、なんかサラッと生じるエラーの代表格がこれなんじゃないかと思うくらい、俺がAS組むとこのエラーにぶち当たるんですが、案外具体的な情報がなくていつも困っていたわけだけれども、いろいろ実験してみたところ、なんとなく原因がわかったので、ブログる。

参考資料

実際に表題のエラーがでるソースコードをおいておくので、cloneしてくだしあ。
https://github.com/kkotaro0111/FlashProf_Conflict_Error

withErrorブランチが、上記エラーが生じる状態、
createClassBブランチが、それが修正された状態その1。
wrapClassブランチが、それが修正された状態その2。

状況

FlashProfessionalのステージ上に、オブジェクトB、Cがある。
オブジェクトBは、FlashProfessionalのライブラリ内でリンゲージを設定されており、クラスとして"classB"を、基本クラスとして"classA"を設定してある。
オブジェクトCは、classC.asという外部ASファイルがあり、その中で"extends classA"つまりクラスAの派生クラスとして宣言されている。FlashProfessional上では、同様にリンゲージされているが、外部ASファイルがあるので、基本クラスが設定されていない(外部ASファイルに設定が移譲されている)。
オブジェクトAは存在しないが、"classA.as"として外部ASファイルが存在しており、オブジェクトBおよびCの親クラスとなっている(はず)。一応、MovieClipから派生している。

オブジェクトBおよびCは、そのMovieClip内にそれぞれ、"share"というインスタンス名を持つオブジェクトが配置されている。つまり、オブジェクトBもCも"this.share"でアクセスできるインスタンスを持っている。

この状態で、コンパイルすると、表題のようなエラーが吐き出される。
この場合、"1152: 継承した定義 classA.share (名前空間 public) にコンフリクトが存在します。"と表示される。

原因

オブジェクトC側で、インスタンス"share"が多重宣言されたことになっているのが原因。
普通に考えたら、オブジェクトBはclassBに関連付けられており、オブジェクトCはclassCに関連付けられているように感じる。確かに、オブジェクトCの方はインスタンス"share"をclassCのインスタンスとして自動宣言されており、その挙動には違和感がない。

ただ、外部ASファイルを作らなかったオブジェクトB(classB)が問題で、コンパイラ的にはclassBというクラスは存在しないことになっているようだ。さしずめ、"var classB:classA = new classA();"として作られた感じだろうか。そのため、オブジェクトB側のインスタンス"share"は、【classAのインスタンスとして自動宣言される】わけだ。コンパイラはこの事実から、【classAは"share"というインスタンスを持つ】と認識する。しかもpublic。

さて、classCはclassAの派生クラスである。つまり、classCは特に"share"というインスタンスを宣言しなくても、"share"インスタンスを持っていることになり、それにアクセスできることになる。しかし、先にあげたように、classCはclassCで独自に"share"が宣言される。そのため、ここで多重宣言が生じ、コンフリクトが起きるわけだ。

解決策

1つは、"classB.as"というファイルを作り、リンゲージの設定で関連付けさせる方法だ(createClassBブランチ)。classB.asがあれば、オブジェクトBは"new classB();"として宣言され、インスタンス"share"もclassBのインスタンスとして宣言される。(おそらく)classAはインスタンス"share"の存在を知ることはない。ただし、この方法では、classAを基本クラスに持つオブジェクトが100個あった場合、外部ASファイルを100個作らなければいけない。大変だ。その場合の解決策がもう一つ方法である。
もう1つは"外部ASファイルを持たないオブジェクトの基本クラスに設定するためのラップクラス"を外部ASファイルで宣言する(wrapClassブランチ)。この場合、例えば"public class WrapClassA extends classA"なクラスを外部ASファイルとして作っておき、オブジェクトBのリンゲージ設定の「基本クラス」に"WrapClassA"を設定する。こうしておくと、オブジェクトCの"share"インスタンスは"classCのインスタンス"として、オブジェクトBの"share"インスタンスは"WrapClassA"のインスタンスとして宣言されるので、classAには影響が及ばなくなるため、オブジェクトCで多重宣言されることはなくなる。
他にも、外部ASファイルを作らず、オブジェクトCの第1フレームに直接書くという手もあるが、AS3のコードをタイムラインに書くのって俺的にナンセンスなので却下だ。

注意

ここに書かれてるFlashProfessionalおよびそのコンパイラの挙動については、あくまで俺が感じた雰囲気を元に予想したものであり、実際に上記のような判断、構成になっているかどうかは不明である。なので、「あぁそういうイメージかー」程度に認識していただきたい。