Javaプログラミング入門
第5回
今日の講義
• 例外
• インターフェース
日常の『例外』とJavaの『例外』
• 普段の『例外』
▫ 「魚は空を飛ばない。けど、トビウオは例外」
▫ 規則に当てはまらないものを意味する

• Java言語の『例外』
▫ プログラムの誤りを検知し、適切なエラー処理を
行うための機構
▫ ...
Java言語の例外
• 例外(exception)
1. 配列の長さを越えた添字で要素を参照した


ArrayIndexOutOfBoundsException

2. ファイルを開こうと思ったが、ファイルがな
かった


FileNot...
例外を起こしてみる
public class ExceptionTest1 {
public static void main(String[] args) {
int[] myarray = new int[3];
System.out.pr...
例外が発生すると後続の処理は行わな
い
• 「代入しました」「終了します」は表示されな
かった
→プログラムが
myarray[100] = 0;
で例外(ArrayIndexOfBoundsException)が発生
したため、処理が中断され...
例外をキャッチする
• 例外の処理を行うことを「例外を受ける」「例
外をcatchする」と言う
• 例外を正しくキャッチすることにより、後続の
処理を続行させることが出来る
例外をキャッチする例
public class ExceptionTest2 {
public static void main(String[] args) {
int[] myarray = new int[3];
try {
System...
例外のイメージ
try {
例外のスロー

} catch (Exception e) {
例外のキャッチ

}
投げられてるのはクラスではなくイン
スタンス
• ArrayIndexOutOfBoundsException
▫ クラス名

• 「 ~Exception を投げる」と言うが、実際に投
げられているのはクラスではなくインスタンス
• catc...
階層化されたメソッド呼び出しから投
げられる例外
public class ExceptionTest3 {
public static void main(String[] args) {
int[] myarray = new int[3]...
実行してみる
コールスタック
• メソッド呼び出しの積み重ねのことをコールス
タック(call stack)と言う
▫ 「呼び出し(call)」「積み重なったもの(stack)」

• 例外が発生した場合、returnとは異なり、1つ前
のメソッドに戻るとは...
メソッドの処理を中断しても大丈夫な
のか?
• やりかけの仕事を途中で放棄してプログラムは
破綻しないのか?
▫ やりかけの仕事を放棄しても、try文を終了する前
に、finallyブロックで終了処理を書くことが出来
る
finallyブロックを使った例
public class ExceptionFinally {
public static void main(String[] args) {
System.out.println("Start");
try...
代表的な例外処理の例
• 数への変換
▫ 文字列を整数値に変換する際に入力された文字が
数値でなかった場合
 NumberFormatException

• ファイル処理
▫ ファイルが存在しなかった場合
 FileNotFoundExc...
NumberFormatException
public class NumberTest {

+ e);

public static void main(String[] args) {
String numstr = "XYZ";
tr...
自分で投げる例外
throws new IOException();
• 予約語throwsの後に投げたい例外のインスタン
スを記述することで、例外を投げることが出来
る
APIライブラリのマニュアル
public FileReader(String fileName)
throws FileNotFoundException
• FileNotFoundExceptionがthrows節によって表
現されている
例外の階層
Object

Throwable

Error

Exception

RuntimeException
それ以外の
Exception
例外の階層
• Throwable(throw + able):投げることが出来るク
ラス
▫ Errorは、もはや動作を継続するのは期待できな
い時に投げられるクラス
▫ Exceptionは、正しく例外処理を行って、動作が
継続することを期...
チェックされる例外ですべきこと
• メソッドの中で
throw new IOException();
と記述していた場合
1. メソッド内のcatch節でその例外をキャッチす
ること
2. メソッドのthrow節でその例外を投げることを
宣言
...
メソッド内のcatch節でその例外を
キャッチする
void someMethod() [
try {
...
throw new IOExcrption();
...
} catch (IOException e) {
...
}
}
メソッドのthrow節でその例外を投げ
ることを宣言
void someMethod() throws IOException {
...
throw new IOExcption();
...
}
「チェックされる例外」の意味
• 例外は「投げっぱなしには出来ない」
• 例外はキャッチするか、キャッチしない場合は
throwして上位のメソッドでキャッチして処理
を行わなければならない
「チェックされない例外」の意味
• 「いつどこで起こってもおかしくないような例
外」
▫ いつ、どこで起きるかわからないので、チェック
できない
例外の階層とcatch節
• 例外を正しくキャッチするには、例外自体の階
層を正しく理解する必要がある
• 投げられた例外をキャッチするのは、一番早く
マッチした例外
マッチする例外
try {

...
throw new IOException();
...
} catch (RuntimeException e) {
...
} catch (IOException e) {
// こちらが実行される
...
投げられた例外は親クラスを使って
キャッチ出来る
try {
...
throw new IOException();
...
} catch (Exception e) { // キャッチされる
...
}
• ExceptionクラスはIO...
例外を用いたプログラミングの注意点
• 例外を用いると、エラーが起きる場所とそのエ
ラーを処理する場所を分けることが出来る
• ただし、try文を注意深く作らなければ、例外が
どこで発生しているかわからなくなる
スタックトレース
• printStackTraceを使うと、どこで例外が発生し
たか見ることが出来る
printStackTraceを使った例
public class ExceptionTest4 {
public static void main(String[] args) {
int[] myarray = new int[3];
tr...
finallyをうまく使う
• finallyブロックは例外が投げられても、投げら
れなくても、finallyブロックは必ず実行される
• finallyブロックの中には必ず行うべき後始末を
記述する
▫ ファイルのクローズ処理、ネットワークの...
メソッドのエラー通知法
1. 戻り値でエラーを示す
▫

jaav.io.InputStreamReaderクラスのread()メ
ソッドでは、ファイルの終端にたどり着き読み
込みが出来なくなった場合は、-1を返す

2. 例外でエラーを示す
...
例外クラスの自作
• ゲームのプレイヤーが死んだ場合に、
DeadPlayerException
▫ Exceptionクラスの子クラスとして作る

• ハイスコアのファイルが読めない場合は、
HiScoreDataIOException
▫ ...
演習1
• 次のようなプログラムを動かしていて、
method1~method3までのいずれかでException
が発生したとする。例外がどのクラスから投げ
られているかわかるように、mainメソッドを修
正しなさい
ExceptionTest5.java
public class ExceptionTest5 {
public static void main(String[] args) {
try {
mehod1(0);
mehod2(0);
meh...
演習2
• 10の会場を求めるつもりで次のプログラムを記
述したが、実行時にStackOverflowErrorという
例外が投げられた。どうしてか。また、このプ
ログラムをどう直せば10の階乗が求められる
か。なお、10の階乗とは
10×9 ...
FactorialTest.java
public class FactorialTest {
public static void main(String[] args) {
System.out.println(factorial(10))...
インターフェースとは
• ここで学ぶインターフェースという単語は、
「人間とコンピュータのやりとりの約束事」
• インターフェースもクラスと同様参照型の一種
• インターフェースは、名前を持ち、フィール
ド、メソッド、スーパーインタフェース、サ...
クラスとインターフェースの違い
• インターフェースが持つフィールドは必ず定数
• インターフェースが持つメソッドは必ず抽象ク
ラス(メソッドは実装されない)
• インターフェースはインスタンスを作ることが
できない
インターフェースの定義
interface Lockable {
boolean lock();
boolean unlock();
}
• interface内で宣言されているメソッドはabstract
がついていなくても自動的に抽象クラスと...
インターフェースの実装
public class Kinko implements Lockable {
@Override
public boolean lock() {
return false;
}
@Override
public bo...
extendsとimplementsの違い
• 「クラスの拡張」extends
• 「インターフェースの実装」implements
• Kinkoクラスはextends節がないため、スーパー
クラスはObjectクラスになる。KinkoでもOb...
JewelBoxクラス(Boxクラスを拡張)を拡
張したLockableJewelBox
public class LockableJewlBox extends JewelBox implements
Lockable {
@Override...
クラス階層図
Lockableを実装
しているクラス

Object

Kinko

Box

JewelBox

LockableJewelBox
KinkoクラスとLockableJewelBoxクラス
の違い
• LockableJewelBoxは、JewelBox、Box、Object
のメソッドをすべて継承している
• LockableJewelBoxは、Lockableも実装して...
例:DebugPrintableインターフェース
• プログラム実行中にインスタンスの内容をデ
バッグ出力する

public interface DebugPrintable {
void debugPrint();
}
DebugPrintableインターフェースを実
装したMyNumberクラス
public class MyNumber implements DebugPrintable {
int a;
public MyNumber(int a) {
...
MyNumberクラスの動き
MyNumber num = new MyNumber(123);
とインスタンスを作ったとすると
num.debugPrint();
は
MyNumberのインスタンス:aの値は 123 です
と表示される
MyFileReaderクラス
• DebugPrintableインターフェースを実装し、FileReaderクラス(ファイル読み込みを行うク
ラス)を拡張する
public class MyFileReader extends FileRea...
MyFileReaderクラスの動き
MyFileReader reader = new
MyFileReader("input.txt");
とインスタンスを作ったとすると
reader.debugPrint();
の実行によって
MyFil...
クラス階層図
Object
MyNumber

Reader
InputStreamReader

FileReader

MyFileReader
インターフェース型の変数
• インターフェースはインスタンスを作ることが
出来ない
DebugPrintable obj = new DebugPrintable(); ☓
DebugPrintable obj = new MyNumber(1...
MyFileReaderの場合
DebugPrintable obj = new MyFileReader(123); ○
変数objはDebugPrintable型なので
obj.debugPrint();
は呼び出す事ができるが、
obj....
メソッドの引数でインターフェースを
利用する
public class MyInspector {
static void inspect(DebugPrintable obj) {
obj.debugPrint();
}
}
引数で与えられた...
インターフェースのフィールド
• インターフェースで宣言したフィールドは必ず
定数になる
• DebugPrintableインターフェースに次のような
フィールドを追加する
▫
▫
▫
▫

NO_ERROR
FILE_ERROR
MEMORY...
インターフェースのフィールド
public interface DebugPrintable {
int NO_ERROR = 0;
int FILE_ERROR = 1;
int MEMORY_ERROR = 2;
String PREFIX...
スーパーインターフェース
• インターフェースはクラスと同様に拡張するこ
とが出来る

public interface FastRunnable extends Runnable {
void fastrun();
}
FastRunnabl...
多重継承とインターフェース
• クラスはスーパークラスを1つしか持つことが出
来ない
• MyMediaClass、MyReaderClass、
MyWriterClassという3つのクラスの性質を持つ
MyReaderWriterClassを...
多重継承とインターフェース
• インターフェースを使うことにより、擬似的に
多重継承を実現することが出来る
• スーパークラスはMyMediaClassのみにし、あと
はインターフェースを使った「メソッド継承」
に統一する
• ただし、継承する...
インターフェースは複数実装出来る
public interface MyReadable {
void read(byte[] data);
}
public interface MyWritable {
void write(byte[] d...
クラスとインターフェースの比較
クラス

インターフェース

インスタンス

作れる

作れない

メソッド

いろいろ

必ずpublic abstract

フィールド

いろいろ

必ずpublic static final

スーパーク...
演習3
• クラスAlphaをスーパークラスに持ち、イン
ターフェースとBetaとGammaを実装したpublic
なクラスDeltaの宣言を記述しなさい。ただし、
クラスの内容は省略可
演習4
• 次のメソッドとフィールドを持つIconInfoとい
うpublicなインターフェースを定義しなさい
▫ 引数はint型で仮引数の名前はiconType、戻り値の
型はImage型で、名前がgetIconであるメソッド
▫ 型はint...
演習5
• 以下のMyMediaPlayableインターフェースを拡
張して、MySoundPlayableという名前のサブイ
ンターフェースを宣言しなさい。追加するメ
ソッドは以下のgetSoundNameである
▫ String getSo...
MyMediaPlayableインターフェース
interface MyMediaPlayable {
void play();
void stop();
void loop();
}
参考文献
• Java言語 プログラミングレッスン[第3版]下
▫ 結城浩[著]
Javaプログラミング入門【第6回】
Javaプログラミング入門【第6回】
Upcoming SlideShare
Loading in …5
×

Javaプログラミング入門【第6回】

868 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
868
On SlideShare
0
From Embeds
0
Number of Embeds
49
Actions
Shares
0
Downloads
12
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Javaプログラミング入門【第6回】

  1. 1. Javaプログラミング入門 第5回
  2. 2. 今日の講義 • 例外 • インターフェース
  3. 3. 日常の『例外』とJavaの『例外』 • 普段の『例外』 ▫ 「魚は空を飛ばない。けど、トビウオは例外」 ▫ 規則に当てはまらないものを意味する • Java言語の『例外』 ▫ プログラムの誤りを検知し、適切なエラー処理を 行うための機構 ▫ 普段の『例外』とは異なる
  4. 4. Java言語の例外 • 例外(exception) 1. 配列の長さを越えた添字で要素を参照した  ArrayIndexOutOfBoundsException 2. ファイルを開こうと思ったが、ファイルがな かった  FileNotFoundException 3. メソッドに与えられた引数が異常な値だった  IllegalArgumentException 4. オブジェクトをたくさん作りすぎてメモリが足 りなくなった  OutOfMemoryException
  5. 5. 例外を起こしてみる public class ExceptionTest1 { public static void main(String[] args) { int[] myarray = new int[3]; System.out.println("代入します"); myarray[100] = 0; System.out.println("代入しました"); System.out.println("代入終了します"); } }
  6. 6. 例外が発生すると後続の処理は行わな い • 「代入しました」「終了します」は表示されな かった →プログラムが myarray[100] = 0; で例外(ArrayIndexOfBoundsException)が発生 したため、処理が中断されたため • 例外が起きたことを「例外が投げられた」「例 外がthrowされた」と言う
  7. 7. 例外をキャッチする • 例外の処理を行うことを「例外を受ける」「例 外をcatchする」と言う • 例外を正しくキャッチすることにより、後続の 処理を続行させることが出来る
  8. 8. 例外をキャッチする例 public class ExceptionTest2 { public static void main(String[] args) { int[] myarray = new int[3]; try { System.out.println("代入します"); myarray[100] = 0; System.out.println("代入しました"); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("代入できませんでした"); System.out.println("例外は" + e + "です"); } System.out.println("終了します"); } }
  9. 9. 例外のイメージ try { 例外のスロー } catch (Exception e) { 例外のキャッチ }
  10. 10. 投げられてるのはクラスではなくイン スタンス • ArrayIndexOutOfBoundsException ▫ クラス名 • 「 ~Exception を投げる」と言うが、実際に投 げられているのはクラスではなくインスタンス • catch (ArrayIndexOutOfBoundsException e)のe はインスタンスを受け取る変数
  11. 11. 階層化されたメソッド呼び出しから投 げられる例外 public class ExceptionTest3 { public static void main(String[] args) { int[] myarray = new int[3]; try { System.out.println("代入します"); myAssign(myarray, 100, 0); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("代入出来ませんでした"); System.out.println("例外は" + e + "です"); } System.out.println("終了します"); } static void myAssign(int[] arr, int index, int value) { System.out.println("myAssignに来ました"); arr[index] = value; System.out.println("myAssignから帰ります"); } }
  12. 12. 実行してみる
  13. 13. コールスタック • メソッド呼び出しの積み重ねのことをコールス タック(call stack)と言う ▫ 「呼び出し(call)」「積み重なったもの(stack)」 • 例外が発生した場合、returnとは異なり、1つ前 のメソッドに戻るとは限らない。同じメソッド 内のcatch節に飛ぶかもしれないし、メソッドの 呼び出し元を遡って、初めて見つかったcatch節 にジャンプすることもある • メソッド呼び出しと例外の仕組みを理解してい ないと、プログラムの動きを見失うことになる
  14. 14. メソッドの処理を中断しても大丈夫な のか? • やりかけの仕事を途中で放棄してプログラムは 破綻しないのか? ▫ やりかけの仕事を放棄しても、try文を終了する前 に、finallyブロックで終了処理を書くことが出来 る
  15. 15. finallyブロックを使った例 public class ExceptionFinally { public static void main(String[] args) { System.out.println("Start"); try { int[] a = new int[3]; System.out.println("代入します"); a[3] = 123; System.out.println("代入しました"); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("例外が発生しました " + e); } finally { System.out.println("finallyブロックです"); } System.out.println("End"); } }
  16. 16. 代表的な例外処理の例 • 数への変換 ▫ 文字列を整数値に変換する際に入力された文字が 数値でなかった場合  NumberFormatException • ファイル処理 ▫ ファイルが存在しなかった場合  FileNotFoundException ▫ ファイルを読んだりクローズする時にエラーが発 生した場合  IOException
  17. 17. NumberFormatException public class NumberTest { + e); public static void main(String[] args) { String numstr = "XYZ"; try { int val = Integer.parseInt(numstr); System.out.println("val = " + val); } catch (NumberFormatException e) { System.out.println("例外が発生しました " } } }
  18. 18. 自分で投げる例外 throws new IOException(); • 予約語throwsの後に投げたい例外のインスタン スを記述することで、例外を投げることが出来 る
  19. 19. APIライブラリのマニュアル public FileReader(String fileName) throws FileNotFoundException • FileNotFoundExceptionがthrows節によって表 現されている
  20. 20. 例外の階層 Object Throwable Error Exception RuntimeException それ以外の Exception
  21. 21. 例外の階層 • Throwable(throw + able):投げることが出来るク ラス ▫ Errorは、もはや動作を継続するのは期待できな い時に投げられるクラス ▫ Exceptionは、正しく例外処理を行って、動作が 継続することを期待するときに投げられるクラス  RuntimeException:実行中に起こり、コンパイラに よって前もってチェックされない例外  その他のException:コンパイラによって前もって チェックされる例外
  22. 22. チェックされる例外ですべきこと • メソッドの中で throw new IOException(); と記述していた場合 1. メソッド内のcatch節でその例外をキャッチす ること 2. メソッドのthrow節でその例外を投げることを 宣言 • どちらか一方を必ずしなければならない
  23. 23. メソッド内のcatch節でその例外を キャッチする void someMethod() [ try { ... throw new IOExcrption(); ... } catch (IOException e) { ... } }
  24. 24. メソッドのthrow節でその例外を投げ ることを宣言 void someMethod() throws IOException { ... throw new IOExcption(); ... }
  25. 25. 「チェックされる例外」の意味 • 例外は「投げっぱなしには出来ない」 • 例外はキャッチするか、キャッチしない場合は throwして上位のメソッドでキャッチして処理 を行わなければならない
  26. 26. 「チェックされない例外」の意味 • 「いつどこで起こってもおかしくないような例 外」 ▫ いつ、どこで起きるかわからないので、チェック できない
  27. 27. 例外の階層とcatch節 • 例外を正しくキャッチするには、例外自体の階 層を正しく理解する必要がある • 投げられた例外をキャッチするのは、一番早く マッチした例外
  28. 28. マッチする例外 try { ... throw new IOException(); ... } catch (RuntimeException e) { ... } catch (IOException e) { // こちらが実行される ... } • IOExceptionはRuntimeExceptionの拡張クラスでは ないため、RuntimeExceptionのcatch節には入らな い
  29. 29. 投げられた例外は親クラスを使って キャッチ出来る try { ... throw new IOException(); ... } catch (Exception e) { // キャッチされる ... } • ExceptionクラスはIOExceptionクラスの親クラ スなため、キャッチすることが出来る
  30. 30. 例外を用いたプログラミングの注意点 • 例外を用いると、エラーが起きる場所とそのエ ラーを処理する場所を分けることが出来る • ただし、try文を注意深く作らなければ、例外が どこで発生しているかわからなくなる
  31. 31. スタックトレース • printStackTraceを使うと、どこで例外が発生し たか見ることが出来る
  32. 32. printStackTraceを使った例 public class ExceptionTest4 { public static void main(String[] args) { int[] myarray = new int[3]; try { System.out.println("代入します"); myAssign(myarray, 100, 0); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("代入出来ませんでした"); System.out.println("例外は" + e + "です"); e.printStackTrace(); } System.out.println("終了します"); } static void myAssign(int[] arr, int index, int value) { System.out.println("myAssignに来ました"); arr[index] = value; System.out.println("myAssignから帰ります"); } }
  33. 33. finallyをうまく使う • finallyブロックは例外が投げられても、投げら れなくても、finallyブロックは必ず実行される • finallyブロックの中には必ず行うべき後始末を 記述する ▫ ファイルのクローズ処理、ネットワークのコネク ションクローズ処理など • finallyブロックの中にはreturn文を記述してはい けない
  34. 34. メソッドのエラー通知法 1. 戻り値でエラーを示す ▫ jaav.io.InputStreamReaderクラスのread()メ ソッドでは、ファイルの終端にたどり着き読み 込みが出来なくなった場合は、-1を返す 2. 例外でエラーを示す ▫ java.io.DataInputStreamクラスのreadCharメ ソッドではIOException、EOEExceptionを返す 3. 別の方法でエラーを示す ▫ java.io.PrintWriterクラスはcheckErrorメソッドを 呼び出して調べる必要がある
  35. 35. 例外クラスの自作 • ゲームのプレイヤーが死んだ場合に、 DeadPlayerException ▫ Exceptionクラスの子クラスとして作る • ハイスコアのファイルが読めない場合は、 HiScoreDataIOException ▫ IOExceptionの子クラスとして作る
  36. 36. 演習1 • 次のようなプログラムを動かしていて、 method1~method3までのいずれかでException が発生したとする。例外がどのクラスから投げ られているかわかるように、mainメソッドを修 正しなさい
  37. 37. ExceptionTest5.java public class ExceptionTest5 { public static void main(String[] args) { try { mehod1(0); mehod2(0); mehod3(0); } catch (Exception e) { System.out.println("例外:" + e); } } static void method1(int x) throws Exception{ } static void method2(int x) throws Exception{ } static void method3(int x) throws Exception{ } }
  38. 38. 演習2 • 10の会場を求めるつもりで次のプログラムを記 述したが、実行時にStackOverflowErrorという 例外が投げられた。どうしてか。また、このプ ログラムをどう直せば10の階乗が求められる か。なお、10の階乗とは 10×9 ×8 ×7 ×6 ×5 ×4 ×3 ×2 ×1 のことである
  39. 39. FactorialTest.java public class FactorialTest { public static void main(String[] args) { System.out.println(factorial(10)); } public static int factorial(int n) { return n * factorial(n -1); } }
  40. 40. インターフェースとは • ここで学ぶインターフェースという単語は、 「人間とコンピュータのやりとりの約束事」 • インターフェースもクラスと同様参照型の一種 • インターフェースは、名前を持ち、フィール ド、メソッド、スーパーインタフェース、サブ インターフェースを持つ
  41. 41. クラスとインターフェースの違い • インターフェースが持つフィールドは必ず定数 • インターフェースが持つメソッドは必ず抽象ク ラス(メソッドは実装されない) • インターフェースはインスタンスを作ることが できない
  42. 42. インターフェースの定義 interface Lockable { boolean lock(); boolean unlock(); } • interface内で宣言されているメソッドはabstract がついていなくても自動的に抽象クラスとなる (メソッドの実装部分{}は記述できない) • インターフェースの名前にはRunnableのように -ableという言葉(接尾語)を付けることが多い
  43. 43. インターフェースの実装 public class Kinko implements Lockable { @Override public boolean lock() { return false; } @Override public boolean unlock() { return false; } } • 「実装」というのは「実際に装備する」という意味
  44. 44. extendsとimplementsの違い • 「クラスの拡張」extends • 「インターフェースの実装」implements • Kinkoクラスはextends節がないため、スーパー クラスはObjectクラスになる。KinkoでもObject のメソッドを使うことが出来る(継承)
  45. 45. JewelBoxクラス(Boxクラスを拡張)を拡 張したLockableJewelBox public class LockableJewlBox extends JewelBox implements Lockable { @Override public boolean lock() { return false; } @Override public boolean unlock() { return false; } }
  46. 46. クラス階層図 Lockableを実装 しているクラス Object Kinko Box JewelBox LockableJewelBox
  47. 47. KinkoクラスとLockableJewelBoxクラス の違い • LockableJewelBoxは、JewelBox、Box、Object のメソッドをすべて継承している • LockableJewelBoxは、Lockableも実装している ので、lock、unlockメソッドも持つ • Kinkoクラスの親はObjectクラスのみ • クラス階層の上ではあまり関係がない ▫ 無関係なクラスでもimplements Lockableを宣言 することによって、「共通のメソッド」をプログ ラムで宣言することが出来る
  48. 48. 例:DebugPrintableインターフェース • プログラム実行中にインスタンスの内容をデ バッグ出力する public interface DebugPrintable { void debugPrint(); }
  49. 49. DebugPrintableインターフェースを実 装したMyNumberクラス public class MyNumber implements DebugPrintable { int a; public MyNumber(int a) { this.a = a; } @Override public void debugPrint() { System.out.println("MyNumberのインスタン ス:aの値は" + a + "です"); } }
  50. 50. MyNumberクラスの動き MyNumber num = new MyNumber(123); とインスタンスを作ったとすると num.debugPrint(); は MyNumberのインスタンス:aの値は 123 です と表示される
  51. 51. MyFileReaderクラス • DebugPrintableインターフェースを実装し、FileReaderクラス(ファイル読み込みを行うク ラス)を拡張する public class MyFileReader extends FileReader implements DebugPrintable { String filename = null; public MyFileReader(String filename) throws FileNotFoundException { super(filename); this.filename = filename; } @Override public void debugPrint() { System.out.println("MyFileReaderのインスタンス:ファイル名は" + filename + "です"); } }
  52. 52. MyFileReaderクラスの動き MyFileReader reader = new MyFileReader("input.txt"); とインスタンスを作ったとすると reader.debugPrint(); の実行によって MyFileReaderのインスタンス:ファイル名は input.txt です と表示される
  53. 53. クラス階層図 Object MyNumber Reader InputStreamReader FileReader MyFileReader
  54. 54. インターフェース型の変数 • インターフェースはインスタンスを作ることが 出来ない DebugPrintable obj = new DebugPrintable(); ☓ DebugPrintable obj = new MyNumber(123); ○ MyNumberはDebugPrintableインターフェースを 実装しているので、MyNumberのインスタンスは DebugPrintable型の変数objに代入出来る
  55. 55. MyFileReaderの場合 DebugPrintable obj = new MyFileReader(123); ○ 変数objはDebugPrintable型なので obj.debugPrint(); は呼び出す事ができるが、 obj.read() はコンパイルエラーになる(インターフェースで 定義されていないため) ((MyFileReader)obj).read(); とキャストすることで使用できるようになる
  56. 56. メソッドの引数でインターフェースを 利用する public class MyInspector { static void inspect(DebugPrintable obj) { obj.debugPrint(); } } 引数で与えられたobjがDebugPrintableインター フェースを実装しているクラスであれば、そのイ ンスタンスのdebugPrintメソッドを呼び出すこと が出来る
  57. 57. インターフェースのフィールド • インターフェースで宣言したフィールドは必ず 定数になる • DebugPrintableインターフェースに次のような フィールドを追加する ▫ ▫ ▫ ▫ NO_ERROR FILE_ERROR MEMORY_ERROR PREFIX
  58. 58. インターフェースのフィールド public interface DebugPrintable { int NO_ERROR = 0; int FILE_ERROR = 1; int MEMORY_ERROR = 2; String PREFIX = "ERROR:"; void debugPrint(); } インターフェースで宣言されているフィールドは、 自動的にpublic static final になる
  59. 59. スーパーインターフェース • インターフェースはクラスと同様に拡張するこ とが出来る public interface FastRunnable extends Runnable { void fastrun(); } FastRunnableはRunnableのサブインターフェー ス
  60. 60. 多重継承とインターフェース • クラスはスーパークラスを1つしか持つことが出 来ない • MyMediaClass、MyReaderClass、 MyWriterClassという3つのクラスの性質を持つ MyReaderWriterClassを作りたいと思っても、3 つのクラスからメソッドやフィールドを継承す ることが出来ない
  61. 61. 多重継承とインターフェース • インターフェースを使うことにより、擬似的に 多重継承を実現することが出来る • スーパークラスはMyMediaClassのみにし、あと はインターフェースを使った「メソッド継承」 に統一する • ただし、継承するのは名前のみで、実装は継承 しない
  62. 62. インターフェースは複数実装出来る public interface MyReadable { void read(byte[] data); } public interface MyWritable { void write(byte[] data); } public class MyReaderWriterClass extends MyMediaClass implements MyReadable, MyWritable { @Override public void write(byte[] data) { } @Override public void read(byte[] data) { } }
  63. 63. クラスとインターフェースの比較 クラス インターフェース インスタンス 作れる 作れない メソッド いろいろ 必ずpublic abstract フィールド いろいろ 必ずpublic static final スーパークラス 1つだけ 持てない スーパーインターフェー ス 複数指定可能 (implementsを使う) class A implements B, c { .... } 複数指定可能 (extendsを使う) interface X extends Y,Z { .... }
  64. 64. 演習3 • クラスAlphaをスーパークラスに持ち、イン ターフェースとBetaとGammaを実装したpublic なクラスDeltaの宣言を記述しなさい。ただし、 クラスの内容は省略可
  65. 65. 演習4 • 次のメソッドとフィールドを持つIconInfoとい うpublicなインターフェースを定義しなさい ▫ 引数はint型で仮引数の名前はiconType、戻り値の 型はImage型で、名前がgetIconであるメソッド ▫ 型はintで名前はICON_16x16、値は1であるフィー ルド ▫ 型はintで名前はICON_32x32、値は2である フィールド
  66. 66. 演習5 • 以下のMyMediaPlayableインターフェースを拡 張して、MySoundPlayableという名前のサブイ ンターフェースを宣言しなさい。追加するメ ソッドは以下のgetSoundNameである ▫ String getSoundName();
  67. 67. MyMediaPlayableインターフェース interface MyMediaPlayable { void play(); void stop(); void loop(); }
  68. 68. 参考文献 • Java言語 プログラミングレッスン[第3版]下 ▫ 結城浩[著]

×