Comments
Description
Transcript
クラス)を作成
平成 16 年度 プログラミング技法 2004/04/17 7.ク ラ ス の 作 成 1.メソッドの作成とクラスの拡張 クラスの拡張(クラスの継承) ・ 既存のクラスを拡張して別のクラス(新しいクラス)を作成すること(子クラスから見た場合) ・別のクラス(新しいクラス)に自分の変数と処理を含めること (親クラスから見た場合) 既存のクラス 変数 親クラス (super クラス) メソッド( ) 継承される 新しいクラス 子クラス (sub クラス) 継承により、 ※ 子クラスは 親クラスの 変数 と メソッド を 継承する (親クラスの内容が"含まれる"と考えるよい. 子クラスには親クラスの内容は記述せずに使える. ) ※ 子クラスに変数やメソッドを記述することで,親クラスからの機能追加を行なえる 継承の方法(クラスの宣言部) class 子クラス名 extends 親クラス 追加する変数(フィールド)の宣言 追加するメソッドの宣言と定義 { ; ; } なお、メソッドの定義方法は 戻り値の型 メソッド名 ( 引数1の型 仮引数1 , 引数 2 の型 仮引数 2 , ・・・){ } ※ 戻り値の型は 「メソッドの型」 と見れる (ex)教科書 P52 リスト 6.2 House.java 1: public class House extends Turtle{ // Turtle を継承 2: public void polygon(int n, int s){ // このメソッドを追加 3: int a =360/n; 4: for(int j=0; j<n;j++){ 5: fd(s); // 親のメソッドを自分のクラスとして利用 6: rt(a); // 親のメソッドを自分のクラスとして利用 7: } 8: } ・・・・・・ 16: } ― 1 − 平成 16 年度 2004/04/17 プログラミング技法 ・House は Turtle から拡張された新しいクラス である ・House 内では Turtle のメソッド fd( ) など全て利用できる ( House が Turtle を継承し,House のメソッドとして利用できる) ・メソッド polygon( ) が設定されている (親クラスのメソッドと polygon( ) が使える) プログラムでは, (1)5,6 行目で fd(s),rt(a) は Turtle クラスの fd(), rt()であるが,自分のメソッド として扱っている。 ここで, fd(s) の記述は this.fd(s) のことであり,this は“自分のインスタンス (House のインスタンス)”を指す (this は省略可) (2)polygon(int n, int s)の n, s は仮引数であり,このメソッドが呼び出された引数の値 が n と s に代入される. <継承に関するワンポイント> まったく新しいクラスを作成する場合では, Object クラスが自動的に継承されている public class A {・・・・・・・} ↑ extends Object が自動的に入っている 2.メソッドの多重定義(オーバーロード) 一つのクラス内に同じ名前で 引数の個数や型の異なるメソッドを定義すること (メソッドの名前と引数の個数と型をまとめた言い方 ⇒ シグネチャ ) void house(int x, int y, int s) シグネチャ void house(int x, int y, int n, int s, int w) シグネチャが異なるため, (コンパイラには)異なるメソッドと見られる 多重定義 (オーバーロード) 3.値を返すメソッド メソッド内で処理した内容を呼ばれた箇所に値を戻すためには以下の文を書く。 return( ただし, 式 式 ) ( なお,( )は記述しなくてもよい ) の型は メソッドの 返値の型 と一致すること また,メソッドの返り値の型が void ならば 値を返す必要はない 4.アクセス修飾子(インスタンス変数の例) (インスタンス変数・・・・インスタンスの状態情報を格納する変数) 利用方法 アクセス修飾子 型名 ― 2 − 変数名 ; 平成 16 年度 プログラミング技法 2004/04/17 アクセス修飾子 public private protected そのクラスの外のいかなるクラスからもアクセス可 そのクラス内のみアクセス可 そのクラスの子クラスのみアクセス可 ※インスタンス変数の場合 private が望ましい (理由) 外から勝手にデータを変更されないようにする (情報隠蔽) (操作方法) データを操作するためのメソッドを作成する 5.コンストラクタ ◎オブジェクト (インスタンス)を作成 するためのメソッド ◎ (さらに,) オブジェクト(インスタンス)の 初期化 を行なうためのメソッド ○ クラス名と同じ名前で 返り値のないメソッド として定義する ○ (通常,) 多重定義 される ※ デフォルトコンストラクタ クラスを定義し,初期化を含まずにオブジェクトを作成すると,自動的に呼び出される 引数のないコンストラクタ (ex)リスト 6.5(教科書 p59 ) Stepper.java −→ 3 つのコンストラクタが記述されている 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: /** x, y という座標に angle の角度の Stepper を生成 */ Stepper(int x, int y, int angle, int n, int size) { super(x, y, angle); //Turtle のコンストラクタ呼び出し this.n = n; //インスタンス変数 n に 引数 n を設定 this.size = size; //インスタンス変数 size の設定 } /** n = 4, size = 100 の Stepper を作成 */ Stepper(int x, int y, int angle) { this(x, y, angle, 4, 100);//上記のコンストラクタ呼び出し } /** 0 引数のコンストラクタ */ Stepper() { super();} //上位コンストラクタを呼び出すだけ L16 Stepper( ){super( );} ⇒ (デフォルト)コンストラクタ (引数なし) L2∼L7,L10∼L13 ⇒ 引数が設定されている場合に呼び出されるコンストラクタ (この場合はデフォルトコンストラクタは呼び出されない) ※ (重要) ここで以下の記号(予約語)に注意 super this ← ← 親クラスを指す 自分自身のオブジェクト(インスタンス)を指す よって,L16:super( ) ← 親クラスのデフォルトコンストラクタの呼び出し L12:this(x,y augle,4,100) ← 自分のクラスのコンストラクタの呼び出し (つまり L2 の呼び出し) ― 3 − 平成 16 年度 2004/04/17 プログラミング技法 ※ 親クラスのコンストラクタの呼び出しの必要性 親クラスで初期化を行なっている可能性があるため,親クラスのコンストラクタを呼び出すこ とで正しく予期化を含めて動作させるため 6.内部クラス (インナークラス) あるクラスの中に定義されたクラス (あるクラス内において,必要とされる機能をもつクラスを外部には見せないで定義する) (例1) 内部クラスの例 public class A { // クラス A の宣言 public static void main( ){ B b; // A のクラス内にあるクラス B のオブジェクトを利用 ……… } public static f( ){ …… } class B { f( ); } } // クラス A のメソッド f( ) クラス B が インナークラス クラス B はクラス A の中にあるので,(クラス A のスコープの 中にあるので)クラス A のメソッドがそのまま使える.(オブジ ェクト作成も参照も必要ない) ※ クラス A のはコンパイル後, A$B.class が作成される. A$B.class は B が A のスコープ内で定義されていることを示す. (例2) 内部クラス(クラス B)を外に出した場合(当然,内部クラスでなくなる) public class A { // クラス A の宣言 public static void main( ){ B b; // A のクラス内にあるクラス B のオブジェクトを利用 ……… } public static f( ){ …… } // クラス A のメソッド f( ) } class B { A a; a.f( ); // クラス B はクラス A とは別物となる // クラス A のメソッドを利用する場合は // クラス A のオブジェクトを作成し,そのメソッドを利用 } 7.匿名内部クラス(無名インナークラス,無名内部クラス) ○ 名前をもたない内部クラス ○ オブジェクトを利用する部分で,そのオブジェクトのクラスの定義が記述されたクラス ○ プログラム中の 1 箇所でしか new 演算子が呼び出されないクラスをその new 演算子の所に定義 を書いたクラス ○ イベント処理によく利用される (利点) 匿名クラスを利用するとクラス名に名前をつける必要がない クラス定義とクラスの利用を同じ場所に置くことができるので煩雑にならない ― 4 − 平成 16 年度 プログラミング技法 2004/04/17 /*** 匿名内部クラスの定義方法 **/ /*** (利用するクラス名は親クラス名に注意,自分の名はない) ***/ new 匿名内部クラスの親クラス名 ( コンストラクタの引数 ) { 匿名内部クラスの本体 } ; (ex) public class MousAnonymousDemo extends Applet{ public void init( ){ ……… addMouseListner( new MouseAdapter( ){ 匿名内部クラスの親クラス名 匿名内部 public void mousePressed( MouseEvent me){ ……… } クラス } ); } } addMouseListner メソッドの実行を行なっ ており,引数に匿名内部クラスのオブジェクト を利用している.そのため,new とクラスの定 義により,オブジェクトを作成している 匿名内部クラス内で定義さ れているメソッド 8.ローカル変数とスコープ ローカル変数とは(一般に)メソッド内部で宣言され,そのメソッドの実行中にしか存在しな い変数 (複数メソッドで同じ名前のローカル変数が使える.同じ名前でもメモリ上は別のところにある ので別物となる) ※ 変数はステートメントブロック内(for 文、while 文など内部)で宣言することができる ⇒ ただし,変数はブロック内部でのみ使用可能である ローカル変数は 利用できる範囲(スコープ)が決まっている スコープの初めで(ローカル変数は)作成され,終わりで削除される (ex) class A { static int s = 400; static int t = 200; // ① void f( ){ int s= 100; // ② (① の s とは別物) System.out.println( "s =" + s + "¥n"); for( int i=0; i<100; i++){ s += i; } System.out.println( "s =" + s + "¥n”); } } ― 5 − スコープ ② の s が利用 できる範囲 i が利用 できる範囲 スコープ