プログラミング 第14 回 - 法政大学 [HOSEI

プログラミング 第14回
インタフェース
[email protected]
プログラミング第14回
1
インタフェースとは
•
•
•
•
クラスと同様の参照型の一種
フィールド,メソッドをもつ
フィールドは定数だけが許される
メソッドはすべて abstract,つまり実装されない
– abstract class では部分的に実装が可能
– abstract class と同様にインスタンスは作れない
• Java言語におけるオブジェクトはこれですべて。
– クラス
– クラスのインスタンス
– インタフェース
プログラミング第14回
2
インタフェースによる契約
interface InterfaceX {
public void
methodX1();
}
• このインタフェースを実装するものを以下甲という。
• このインタフェースを実装するクラスを,どのような
クラスであるか関心をもたずに信じて利用するもの
を以下乙という。
プログラミング第14回
3
インタフェースの実装者(契約者甲)
public class ClassB
implements InterfaceX {
ClassC otsu;
...
public void methodX1(){
...
}
public void myInit(){
「InterfaceXに定められ
たメソッド群をすべて実
装していますよ。」とい
う宣言。これによりこの
クラスは本来の型であ
るClassBだけでなく,
InterfaceXという型もも
つことになる。
otsu=new ClassC();
otsu.setKo(this);
}
...
}
プログラミング第14回
4
インタフェースの利用者(契約者乙)
public class ClassC {
InterfaceX
ko;
pubic void setKo(Interface ko){
this.ko=ko;
}
private void someMethod(){
ko.methodX1();
}
...
}
プログラミング第14回
このクラスは
InterfaceXを実装し
ているクラスならど
んなクラスであろう
と信じて使う。だか
ら変数koの型はイ
ンタフェースで宣
言している。実際
にどのようなクラス
がsetKo()で渡され
て来ても,その中
身には関知しない。
5
多重継承とインタフェース
• 1つのクラスで複数のインタフェースを実装
することができる。
• 多くの型をもつことができる。これは多重
継承を実質可能にしている。abstract クラス
ではこのようなことができない。
プログラミング第14回
6
例 クラス図
<<interface>>
X
ClassA
<<interface>>
Y
ClassB
プログラミング第14回
<<interface>>
Z
ClassC
7
この結果
• X[]={new
• X x=new
• Y y=new
• Z z=new
A(), new B()};
B();
B();
B();
• のようなことができる。
プログラミング第14回
8
Lockable.java(List 14-1,p.167)
interface Lockable {
boolean lock();
boolean unlock();
}
プログラミング第14回
9
Kinko.java(List 14-2, p.108)完全版
class Kinko implements Lockable{
private boolean locked=false;
public boolean isLocked(){ return locked;}
public boolean lock(){
if(locked==false){
locked=true;
System.out.println("Lockされました。");
}else{
System.out.println("すでにLockされています。");
}
return locked;
}
プログラミング第14回
10
Kinko.java (2)
public boolean unlock(){
if(locked==true){
locked=false;
System.out.println("Lockが解除されました。");
}else{
System.out.println("Lockされていません。");
}
return locked;
}
}
プログラミング第14回
11
LockableTest.java
public class LockableTest{
public static void main(String[] args){
Lockable x;
x=new Kinko();
x.lock();
x.unlock();
}
}
プログラミング第14回
12
実行結果
Lockされました。
Lockが解除されました。
プログラミング第14回
13
課題
• Lockableインタフェースを実装するクラス
Houseを作成せよ。
– lock されると「準備中」とprintする
– unlock されると「営業中」とprintする
• LockableTestを改造し,LockableTest2とせ
よ。
– Lockableの長さ2の配列にKinkoとHouseのイ
ンスタンスを格納し,動作を検証する。
プログラミング第14回
14
解答例 House.java(1)
class House implements Lockable{
private boolean locked=false;
public boolean isLocked(){ return locked;}
public boolean lock(){
if(locked==false){
locked=true;
System.out.println("準備中");
}else{
System.out.println("既に準備中ですよ。");
}
return locked;
}
プログラミング第14回
15
House.java (2)
public boolean unlock(){
if(locked==true){
locked=false;
System.out.println("営業中");
}else{
System.out.println("既に営業中ですよ。");
}
return locked;
}
}
プログラミング第14回
16
解答例 LockableTest2.java
public class LockableTest2{
public static void main(String[] args){
Lockable[] x=new Lockable[2];
x[0]=new Kinko();
x[1]=new House();
x[0].lock();
x[0].unlock();
x[1].lock();
x[1].unlock();
}
}
プログラミング第14回
17
余裕のある人へ
• 次に紹介するのは swing の JFrame を拡張し,
Lockable インタフェースを実装するクラスの例で
ある。
– 単体テストのためのmainメソッドも用意してある。
• 結合テストドライバとして LockableTest3 を用意し
てある。
– 長さ3の配列 x[]にKinko,House,SwingKinkoのイン
スタンスを格納している。
– コマンドプロンプトからインデックスと“lock”または
“unlock”をスペースで区切って入力する。
– どういう動きをするだろうか。
プログラミング第14回
18
SwingKinko.java (1)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class SwingKinko extends JFrame
implements Lockable, ActionListener{
private boolean locked;
private JButton lock, unlock, quit;
private JTextField message;
private JPanel jp;
プログラミング第14回
19
SwingKinko.java (2)
public SwingKinko(){
super("Swing Kinko");
setGUI();
}
public boolean lock(){
locked=true;
message.setText("ロックされています");
return locked;
}
public boolean unlock(){
locked=false;
message.setText("ロック解除中");
return locked;
}
プログラミング第14回
20
SwingKinko.java (3)
private void setGUI(){
jp=new JPanel();
getContentPane().add(jp);
lock=new JButton("Lock");
lock.addActionListener(this);
unlock=new JButton("Unlock");
unlock.addActionListener(this);
quit=new JButton("Quit");
quit.addActionListener(this);
message=new JTextField(30);
message.setEditable(false);
プログラミング第14回
21
SwingKinko.java (4)
jp.add(lock);
jp.add(unlock);
jp.add(quit);
jp.add(message);
setSize(new Dimension(400,100));
setVisible(true);
}
プログラミング第14回
22
SwingKinko.java (5)
public void actionPerformed(ActionEvent e){
Object obj=e.getSource();
if(obj==lock){
lock();
} else if (obj==unlock){
unlock();
} else if (obj==quit){
System.exit(0);
}
}
プログラミング第14回
23
SwingKinko.java (6)
// For unit test
public static void main(String[] args){
new SwingKinko();
}
}
プログラミング第14回
24
LockableTest3.java (1)
import java.io.*;
public class LockableTest3{
public static void main(String[] args){
Lockable[] x
={new Kinko(),new House(),new SwingKinko()};
BufferedReader reader
=new BufferedReader(
new InputStreamReader(System.in),1);
String line, token1, token2;
int target=0; int sep;
プログラミング第14回
25
LockableTest3.java (2)
try{
while(!((line=reader.readLine()).equals("quit"))
&& (sep=line.indexOf(" "))>0){
token1=line.substring(0,sep).trim();
token2=line.substring(sep+1).trim();
target=Integer.parseInt(token1);
if(token2.equals("lock")){
x[target].lock();
}else if(token2.equals("unlock")){
x[target].unlock();
}
}
プログラミング第14回
26
LockableTest3.java (3)
}catch(IOException e){System.exit(1);
}catch(NumberFormatException e){System.exit(2);
}
System.exit(0);
}
}
プログラミング第14回
27
ActionListenerインタフェースの契約
• JButton のインスタンスたちは契約者乙
– addActionListener(甲)により契約希望
者の登録を待つ。
– 登録されている甲に対して,必要なときに
actionPerformed()を呼び出す。
• SwingKinko のインスタンスは契約者甲
– actionPerformed()をしっかり定義する義
務がある。
プログラミング第14回
28
ActionListener契約開始
lock:JButton
unlock:JButton
quit:JButton
addActionListener(this);
SwingKinko
プログラミング第14回
29
ActionListener契約履行と仕事の連携
ボタンが押された
lock:JButton
unlock:JButton
quit:JButton
actionPerformed(actionEvent);
どの契約者乙からやって来たか判別して,
それに応じて処理をおこなう。
SwingKinko
プログラミング第14回
30