レポート#5

(12/14)(Sun)   035717B   金城満久
課題
講義資料オブジェクト指向プログラムJava1&2の中のサンプルプログラム について考察せよ.
考察
クラス変数とローカル変数
クラス変数(メンバ変数ともいう.)はオブジェクトの状態を保持する変数 です.オブジェクトに属し,どのメソッド,コンストラクタにも属しません, そのため,クラス変数は複数のメソッド,コンストラクタで共通して使用す ることができます. 逆にローカル変数は各メソッド,コンストラクタに限定して使用する変数 で他のメソッド,コンストラクタから使用することはできません. クラス変数のスコープはクラス変数を宣言したクラスの{}内です.ローカ ル変数のスコープはローカル変数を宣言したメソッド,コンストラクタの{} 内です.
static変数
クラス変数,メソッドを宣言する際,static修飾子が付与されたものをク ラスメンバ変数,クラスメソッド,static修飾子が付与されていないものを インスタンスメンバ変数,インスタンスメソッドと言い,両者で性質が異な ります. クラスメンバ変数,クラスメソッドはそのクラス内で1つという位置付け です.そのクラスからいくつオブジェクトを生成してもオブジェクトごとに メンバ変数,メソッドが割り当てられることはありません. インスタンスメンバ変数,インスタンスメソッドはオブジェクトごとに存 在します.クラスからオブジェクトが生成されるとそれぞれのオブジェクト に対し,インスタンスメンバ変数,インスタンスメソッドが割り当てられま す. クラスメンバ変数,クラスメソッドはオブジェクトに依存しないため,オ ブジェクト指向という観点からいえばそれほど使用されるということはあり ません.クラスメンバ変数,クラスメソッドは以下のケースにおいてよく使 用されます.
  1. オブジェクト間で共通の値を保持したいときにクラスメンバ変数を使用しま す.
  2. 定数を宣言する際に,final修飾子と共に使用されます.ロケール定数な ど標準APIで用意されている定数はほとんどstatic finalで宣言されてい ます.
  3. 公式的な処理を行うメソッドにクラスメソッドを使用します.クラス Mathで用意されているsin,cosなどはstatic修飾子が付与され宣言され ています.
  4. オブジェクトが生成されていなくても処理を行う必要があるときにクラ スメソッドを使用します.クラスメソッドはオブジェクトに依存しないた め,オブジェクトが生成されていなくても実行できます.mainメソッドは オブジェクトを生成する前に実行する必要があるため,static修飾子をつ けて宣言しています.
コンストラクタ
コンストラクタはオブジェクトを生成する際に必ず実行される初期化処 理を記載した部分です.コンストラクタに宣言は以下の枠内のフォーマッ トで構成されています.
アクセスレベル コンストラクタ名 (引数型 引数名)
アクセスレベルはコンストラクタが同一クラス内からしか実行できない, どのクラスからでも実行できるなどを指定するために使用します.(アク セスレベルについては,アクセス制御のところで詳しく行います.)コン ストラクタ名は屬するクラスと同じ名前になります.(引数型 引数名)は 初期化処理を実行する際に呼び出し元から渡される値の型とコンストラク タ内で使用される変数名を表します.コンストラクタ宣言における必須項 目はコンストラクタ名(引数型 引数名)です.コンストラクタ宣言時に付 与できる修飾子はアクセスレベルのみです.クラス内にコンストラクタを 宣言しない場合,コンパイル時に引数をもたず何の処理も行わないデフォ ルトコンストラクタと言うものが生成されます.クラス内に1つでもコン ストラクタが宣言されている場合はデフォルトコンストラクタは生成され ません. コンストラクタは引数の型や引数の数を変更することで1クラス内に複 数宣言することができます.引数の型と引数の数が同じコンストラクタを 1クラス内で複数宣言することはできません.コンパイルエラーとなりま す.
staticイニシャライズ
sitaticイニシャライズは,オブジェクト宣言の際に一度だけ自動的に 実行されるメソッドです.これはstaticというキーワードの後ろに,{}で囲 まれたコードのブロックで構成されます.staticイニシャライズはコンスト ラクタよりも早く実行され,また,クラスを呼び出す際に実行されるので, オブジェクトを複数宣言しても,インスタンスごとにイニシャライズが実行 されることはありません.staticイニシャライズは1つのクラス内で何個で も持てますが,他のクラスのクラス変数やインスタンスメソッドを持つこと はできません.
オーバーロード
オーバーロードとは,同一クラス内で,メソッド名が同一で引数の型, 数.ならび順が異なるメソッドを複数定義することを言います. オーバーロードを定義する際には以下の規定があります.
  1. 異なるメソッドと認識される部分は,メソッドの次の箇所です.「引数 の型」,「引数の数」,「引数の並び順」.
  2. 次の箇所が異なっていても異なるメソッドとは認識されません.コンパ イルエラーとなります.「戻り型」,「アクセスレベル」,「引数名」, 「throws節」.
アクセス制御
アクセスレベルを指定することにより他のクラスから自クラスのメンバ 変数にアクセスさせないなどを指定することができます.アクセスレベル には,次の4つがあります.
public
publicが付与されたメンバ変数,メソッドはどこからでも参照することが できます.publicは指定できるアクセスレベルのうち,もっとも参照制限が低 いものです.
protected
protectedが付与されたメンバ変数,メソッドは同一クラス,同一パッケー ジ,サブクラスから参照することができます.注意点はサブクラスからアクセ スできるのはサブクラスのオブジェクトを通してのみということです.サブク ラスからスーパークラスのオブジェクトを通して参照することはできません.
無指定(デフォルト)
アクセスレベルが無指定(デフォルト)のメンバ変数,メソッドは同一クラ ス,同一パッケージから参照することができます.サブクラスが同一パッケー ジ内にあれば,サブクラスからもアクセスすることができます.
private
privateが付与されたメンバ変数,メソッドは同一クラスからのみ参照す ることができます.privateはアクセスレベルの中で最も参照制限が強いもの です.セキュリティを考えるとメンバ半数は,特別な理由がない限りprivate アクセスレベルをつけて宣言します.
継承
新たなクラスを作成する際,1からクラスを作成するのではなく元々あ るクラスの型に新しい機能のみを付与したほうがいい場合があります.そ の時,クラスの継承を行われます.継承される側のクラスをスーパークラ ス,継承する側のクラスをサブクラスと言います.1つのサブクラスが継 承できるスーパークラスは1つまでです.
class サブクラス名 extends スーパークラス名{クラス本体}
クラスの継承について注意点が4つあります.
  1. スーパークラスでprivate修飾子を付与して宣言されているメンバ変数・メ ソッドはサブクラスから参照することはできません.
  2. スーパークラスでアクセスレベル無指定(デフォルト)で宣言されているメン バ変数・メソッドはサブクラスがスーパークラスと同一パッケージである限り サブクラスから参照することができます.
  3. final修飾子が付与されたスーパークラスを継承することはできません.
  4. スーパークラスで宣言されたコンストラクタはサブクラスに継承されません. サブクラス側でコンストラクタを宣言しなおすか,サブクラスのコンストラク タ内でスーパークラスのコンストラクタを呼び出す必要があります.
super
superはサブクラスのインスタンスメソッド内,コンストラクタ内にお いてスーパークラスのメンバ変数,メソッド,コンストラクタを参照する 際に使用します.サブクラスのクラスメソッド内でsuperを利用すること はできません.なぜなら,superは現在実行しているオブジェクトのスー パークラスのオブジェクトを表すため,オブジェクトに依存しないクラス メソッドはsuperを持ちません. superは以下のケースにおいてよく使用されます.
  1. オーバーライドを行ったサブクラスにおいて,スーパークラスのインスタン スメソッドを参照したい場合に使用します.
    super. メソッド(引数値,・・・);
  2. 隠ぺいを行ったサブクラスにおいて,スーパークラスのインスタンスメンバ 変数を参照したい場合に使用します.
    super. メンバ変数;
  3. サブクラスのコンストラクタからスーパークラスのコンストラクタを参照し たい場合に使用します.この例の詳細についてはコンストラクタを参照してく ださい.
    super(引数値,・・・);
this
thisはインスタンスメソッド内,コンストラクタ内,で使用し,現在処 理を行っているオブジェクトを表します.インスタンスメソッドや門簾トラ クタから他のメソッドやメンバ変数を参照する場合,オブジェクト変数を指 定せず参照することができます.それは,インスタンスメソッド,コンスト ラクタは現在のオブジェクトを表すthisを持っているためです.単純名で参 照していますが,実はコンパイラによりthis,単純名に変換されています. これらの理由より,オブジェクトに依存しないクラスメソッド内ではthisを 使用することはできません. thisは以下のケースにおいてよく使用されます.
  1. メンバ変数の陰ぺいを行う場合,インスタンスメソッド内,コンストラ クタ内で陰ぺいされたメンバ変数を参照する際に使用します.
    this. メンバ変数;
  2. 複数のコンストラクタを宣言し,あるコンストラクタから別のコンスト ラクタを参照する場合に使用します.
    this (引数値,・・・);
abstract
abstractはクラス・メソッド宣言時に付与し,クラス・メソッドを抽象 クラス(abstractクラス)・抽象メソッド(abstractメソッド)として宣言し ます.抽象クラスはそのクラス自身のオブジェクトを生成することはでき ません.通常抽象クラスは実装のないいくつかの抽象メソッドを持ってい ます.抽象クラスをサブクラスで継承し,そのサブクラス内で抽象クラス で実装されていない抽象メソッドを実装(オーバーライド)しオブジェクト を生成する形をとります. 抽象メソッドは以下の枠内のフォーマットで宣言されます.抽象メソッ ドは実装を持たないため,{}は必要ありません.
abstract 戻り型 メソッド名 (引数型 引数名);
抽象クラスは以下の枠内のフォーマットで宣言されます.
abstract class クラス名 {クラス本体}
抽象クラスには以下のルールがあります.
  1. 抽象クラスのオブジェクトを生成することはできません.
  2. 抽象クラスには抽象メソッドがあってもいいし,抽象メソッドでないメソッ ドがあってもいいです.しかし,抽象メソッドがあるクラスは必ず抽象クラス として宣言しなければいけません.
  3. 抽象メソッドがない,抽象クラスを宣言することもできます.必ず継承が行 われ,なんらかのメソッドの変更があることを表します.
  4. 抽象クラスを継承したサブクラスで抽象メソッドを実装(オーバーライド)し ない場合,そのサブクラスは抽象クラスとして宣言されます.
interface
インターフェースとは,ある特定の機能の概要を記述したものです.イ ンターフェースを実装したクラスは,同一のインタフェースを実装したク ラスとの間においてある特定の機能の概要を共通に持ちます.機能概要の 詳細はそれぞれのクラスで定義します. インタフェースの利点の1つとしてクラスが複数のインタフェースを実 装できると言うのがあります.ある特定の機能の概要をクラスに実装する 方法としてextendsを使用してスーパークラスを継承するという方法もあ ります.しかしこの場合複数のスーパークラスを継承することはできませ ん.Javaでは複数のスーパークラスの継承(多重継承)が認められていない ためです.また,extendsによりスーパークラスを継承すると言うことは 継承したサブクラスと継承されたスーパークラスの間にクラス関係を持つ と言うことになります.スーパークラスとっサブクラスの間にクラス関係 が見受けられない場合においてもこのような継承を行うことはクラス設計 上不適切です.このような場合はインタフェースを使用します.インタ フェースの実装はクラス関係に依存しません. インタフェースの宣言は以下の枠内のフォーマットにより構成されます. interfaceとインタフェース名は必須項目です.
public interface インタフェース名
extends スーパーインタフェース名,・・・
インタフェースを実装したクラスでメソッドの本体を定義すると言うこ とを考えると,abstractクラスを継承したクラスでabstractメソッドの 本体を定義するというのとよく似ています.インタフェースとabstract クラスには以下に示すような違いがあります.
  • インタフェースではどのメソッドも本体を定義することはできませんが, abstractクラスには本体を定義したメソッド(abstractでないメソッド)を含め ることができます.
  • インタフェースは複数実装できますが,abstractクラスは1つのみしか継承 できません.(多重継承がサポートされていないため).
  • abstractクラスは継承したクラスとの間にクラス関係を意識する必要があり ますが,インタフェースは実装したクラスとの間にクラス関係を意識する必要 はありません.
インタフェースの実装はimplementsを使用して行います.インタフェー スは1つのクラスに対し,複数実装することもできます.また,クラスが extendsを使用する場合は,implementsはextendsの後に指定します.
class クラス名 implements インタフェース名,・・・
class クラス名 extends スーパークラス名 implements インタフェース名
反省・感想
自分の作ったプログラムならすぐに考察を書けるのですが,サンプルプロ グラムの場合,どう書いていいのか悩みました.abstractとinterfaceがま だちょっとややこしい感じです.
参考文献
Javaの道

<ホーム>