おくればせながら、継承に関する話題を少しまとめます。
extends
サブクラスを定義するには extends キーワードを使います。
// 親クラスの定義 public class MyBase { public function hello():String { return "hello"; } } // サブクラスの定義 public class MySub extends MyBase { }
サブクラスのオブジェクトは親クラスのオブジェクトと同様に使うことができます。
// MyBase 型の変数に代入 var base:MyBase = new MyBase(); var sub:MyBase = new MySub(); // MyBase 型の引数を持つ関数にわたす needBase(sub); needBase(base); public function needBase(obj:MyBase):void { trace(obj.hello()); }
逆に親クラスはサブクラスの代わりにはなりません、が、下のコードは -strict オプションを付けなければ実行できます。
var sub:MyBase = new MySub(); needSub(sub); public function needSub(obj:MySub):void { trace(obj.hello()); }
アクセス制限
プロパティの宣言に private を指定すると、他のクラスからは参照できなくなります。また、public を指定した場合は、どのクラスからも参照できます。
protected を指定したプロパティは、継承したクラスからは参照ができます。デフォルトである internal の場合は、同じパッケージ内のクラスであれば参照できます。
少し注意が必要なのは、protected の場合、他のパッケージのクラスであってもサブクラスであれば参照可能なことです。逆に、protected のプロパティは同じパッケージ内のクラスでもサブクラスでなければ参照できません。
また、internal のプロパティは同じパッケージ内のサブクラスのみにしか継承されません。
ちょっと例を見てみましょう。まず、foo というパッケージに FooBase クラスを定義します。クラス内には protected と internal の2種類の関数を定義します。
package foo { public class FooBase { protected function protectedFunc():void { } internal function internalFunc():void { } } }
次に、bar というパッケージに上記の FooBase のサブクラスを定義します。関数をオーバーライドするため override キーワードを使っています。
package bar { import foo.FooBase; public class BarSub extends FooBase { // 親クラスの定義をオーバーライド override protected function protectedFunc():void { } // こっちはオーバーライドできないはず override internal function internalFunc():void { } } }
これをコンパイルしてみると、protectedFunc() は通りますが、internalFunc() の方はそんな関数は見つからないといわれてしまいます。
また、サブクラス内のコードで、直接親クラスの protected プロパティを参照することはできません。
public class BarSub extends FooBase { public function callProtected():void { var foo:FooBase = new FooBase(); // protected のメソッドを呼び出してみる foo.protectedFunc(); } }
上記の例の場合、callProtected() が呼ばれるとエラーが発生します。
コメントする