• 検索結果がありません。

第7回 継承とインターフェ イス

N/A
N/A
Protected

Academic year: 2021

シェア "第7回 継承とインターフェ イス"

Copied!
46
0
0

読み込み中.... (全文を見る)

全文

(1)

第7回 継承とインターフェ イス

~オブジェクト指向の真髄に挑戦!~

(2)

学習目標

継承とインターフェイスを利用したプ ログラムが書ける

継承を使う利点を説明できる

Java

で継承を使ったプログラムが書ける

ポリモーフィズムを使ったプログラムが書 ける

(3)

7.1 継承

 7.1.1

配列リストと連結リストの性能比

 7.1.2

継承

 7.1.3 Java

で継承を使ったプログラムを

書く

(4)

7.1.1 配列リストと

連結リストの性能比較

public static void main(String[] args) { long startTime;//開始時間を保存する long endTime; //終了時間を保存する //--- 配列リストの性能を測定する --- // 商品種類配列リストを生成する

ItemTypeArrayList itemTypeArrayList = new ItemTypeArrayList();

startTime = System.currentTimeMillis();//開始時間を測定する // 商品種類を 1 万件登録する

for(int i=0;i<10000;i++){

itemTypeArrayList.add(new ItemType(1001,"コーラ ",120));

}

endTime = System.currentTimeMillis();//終了時間を測定する

System.out.println("かかった時間は "+ (endTime - startTime) + "ミリ秒です ");

//--- 連結リストの性能を測定する --- // 商品種類連結リストを生成する

ItemTypeLinkedList itemTypeLinkedList = new ItemTypeLinkedList();

startTime = System.currentTimeMillis();//開始時間を測定する // 商品種類を 1 万件登録する

for(int i=0;i<10000;i++){

itemTypeLinkedList.add(new ItemType(1001,"コーラ ",120));

}

例題

7-1

(5)

同じ意味の数字は定数に

前回のバグの原因

オブジェクト指向以前の問題です

//

商品種類を保存する配列を生成

itemTypeArray = new ItemType[10];

//

商品種類を保存するための変数を初期化する ( 実は不要 ) // 何も入っていないことを

null

として扱う

for(int i=0;i<10;i++){

itemTypeArray[i] = null;

}

など、全部で4ヶ所 あります。

(6)

同じ意味の数字は定数に

「同じ意味を何度も書かない」がプロ グラムの基本です

private int ARRAY_SIZE = 10000;// 配列の大きさ

//

商品種類を保存する配列を生成

itemTypeArray = new ItemType[ARRAY_SIZE];

//

商品種類を保存するための変数を初期化する ( 実は不要 ) // 何も入っていないことを

null

として扱う

for(int i=0;i<ARRAY_SIZE;i++){

itemTypeArray[i] = null;

配列の大きさを 保存しておく変数 を作ります

変更する必要が なくなりますね。

例題

7-1

(ItemTypeArrayList.java)

(7)

① ほとんど同じコードが 2 度

public static void main(String[] args) { long startTime;//開始時間を保存する long endTime; //終了時間を保存する //--- 配列リストの性能を測定する --- // 商品種類配列リストを生成する

ItemTypeArrayList itemTypeArrayList = new ItemTypeArrayList();

startTime = System.currentTimeMillis();//開始時間を測定する // 商品種類を 1 万件登録する

for(int i=0;i<10000;i++){

itemTypeArrayList.add(new ItemType(1001,"コーラ ",120));

}

endTime = System.currentTimeMillis();//終了時間を測定する

System.out.println("かかった時間は "+ (endTime - startTime) + "ミリ秒です ");

//--- 連結リストの性能を測定する --- // 商品種類連結リストを生成する

ItemTypeLinkedList itemTypeLinkedList = new ItemTypeLinkedList();

startTime = System.currentTimeMillis();//開始時間を測定する // 商品種類を 1 万件登録する

for(int i=0;i<10000;i++){

itemTypeLinkedList.add(new ItemType(1001,"コーラ ",120));

}

同じ仕事

例題

7-1

(Example7_1.java)

(8)

② どうしたらメソッド化でき るか?

今回は、この2つの仕事のメソッド化 を考えます

考えてみましょう

(9)

仕事が同じ意味をもつかどう か

< A >

配列リストの性能を測る

配列リストを生成する

開始時間を測定する

配列リストに

1

万件追加する

終了時間を測定する

かかった時間を表示する

< B >

連結リストの性能を測る

連結リストを生成する

開始時間を測定する

連結リストに

1

万件追加する

終了時間を測定する

(10)

仕事は同じ意味を持つ

<仕事を>

「リスト」の性能を測る

「リスト」を生成する

開始時間を測定する

「リスト」

1

万件追加する

終了時間を測定する

かかった時間を表示する

ただし、「リスト」という意味のカタ マリができた場合

(11)

型が違う

型が違うので、今までの方法ではまと められない

//---

配列リスト版 ---

ItemTypeArrayList itemTypeArrayList = new ItemTypeArrayList();

・・・

itemTypeArrayList.add(new ItemType(1001,"

コーラ "));

//---

連結リスト版 ---

ItemTypeLinkedList itemTypeLinkedList = new ItemTypeLinkedList();

・・・

itemTypeLinkedList.add(new ItemType(1001,"

コーラ "));

まとめられない

(12)

I t emTypeAr r ayLi st + add( )

+ del et e( ) + sear ch( ) + di spl ay( ) Mai n

+ mai n( )

1 1

I t emTypeLi nkedLi st + add( )

+ del et e( ) + sear ch( ) + di spl ay( ) 1

1

1 1

1 1

型が違う

問題の原因は配列リストと連結リスト を違う型として捉えていること

「リスト」という意味は同じだが、違うク ラス

意味は同じなのに

(13)

7.1.2 継承

① 継承

② 継承をクラス図で表現する

(14)

① 継承

「リスト」という意味のカタマリができれば、その カタマリに対して性能を測るプログラムができる

継承

を使って型の違う

クラスの意味のカタマリをつくる

<仕事を>

「リスト」の性能を測る

「リスト」を生成する

開始時間を測定する

「リスト」

1

万件追加する

終了時間を測定する

かかった時間を表示する

(15)

継承

共通の意味を持つクラス

(商品種類のリスト)

I t emTypeArr ayLi st + add( )

+ del et e( ) + sear ch( ) + di spl ay()

I t emTypeLi nkedLi st + add( )

+ del et e( ) + sear ch( ) + di spl ay( )

共通の意味をクラスに

I t emTypeLi st + add( )

+ del et e( ) + sear ch( ) + di spl ay( )

抽象化

「リスト」という抽象クラスを定義す る

(16)

I t emTypeLi nkedLi st + add( )

+ del et e( ) + sear ch( ) + di spl ay( )

I t emTypeAr r ayLi st + add( )

+ del et e( ) + sear ch( ) + di spl ay( ) I t emTypeLi st

+ add( ) + del et e( ) + sear ch( ) + di spl ay( )

② クラス図で表現する

ItemTypeLinkedList

ItemTypeList

サブクラス

ItemTypeList

ItemTypeArrayList

スーパークラス

(17)

同じ意味に見える

 Example

は、新しい語彙である「リス

ト」クラスに対してプログラムするこ とができます

配列リストか連結リストか意識しなくて済

より意味が明確なプログラムに

I t emTypeLi st + add( )

+ del et e( ) + sear ch( ) + di spl ay( )

I t emTypeAr r ayLi st + add( )

I t emTypeLi nkedLi st + add( )

Mai n + mai n( )

1 2

1 2

(18)

7.1.3 Java で継承を

使ったプログラムを書く

① スーパークラスの変数への代入

 ② Java

の記法

③ 抽象クラスとインターフェイス

④ 継承

vs

インターフェイス

(19)

① スーパークラス の変数への代入

//---

配列リスト版 ---

ItemTypeArrayList itemTypeArrayList = new ItemTypeArrayList();

//---

連結リスト版 ---

ItemTypeLinkedList itemTypeLinkedList = new ItemTypeLinkedList();

itemTypeArrayList

ItemTypeArrayList

インスタンス

itemTypeLinkedList

ItemTypeLinkedList

インスタンス

基本的に

(20)

① スーパークラス の変数への代入

//---

配列版 ---

ItemTypeList itemTypeList = new ItemTypeArrayList();

//---

連結リスト版 ---

ItemTypeList itemTypeList = new ItemTypeLinkedList();

itemTypeList ItemTypeArrayList

インスタンス

ItemTypeLinkedList

インスタンス

スーパークラスの変数には サブクラスのインスタンスも 代入することができる

(21)

入っている

インスタンスによって切り替 わる

ItemTypeList itemTypeList;//スーパークラスの変数を用意する //--- 配列版 ---

itemTypeList = new ItemTypeArrayList();//配列版インスタンスを代入

itemTypeList.add(new ItemType(1001,"コーラ ")); // 配列版インスタンスに追加され ます

//--- 連結リスト版 ---

itemTypeList = new ItemTypeLinkedList();// 連結リスト版インスタンスを代入

itemTypeList.add(new ItemType(1001,“コーラ” )); // 連結リスト版インスタンスに追 加されます

変数に入っているインスタンスによって、自動的に切り替えられます

Example

は対象を考える必要はなくなり、コードが共通化できます

(22)

入っている

インスタンスによって切り替 わる

itemTypeList

[5]

[4]

[3]

[2]

[1]

[0]

102番地 コーラ

22(id)

null ソーダ

23(id)

itemTypeList add()

add()

ItemTypeArrayList

インスタンス

ItemTypeLinkedList

インスタンス

(23)

② Java の文法 ( スーパークラ ス )

// 商品種類リストスーパークラス

public class ItemTypeList { //

商品種類を追加するメソッド

public void add(ItemType addItemType){

//

何も書かないくてよい

}

//

商品種類を表示するメソッド public void display(){

//

何も書かないくてよい

}

スーパークラスには特別なことを 記述する必要がありませんが、

メソッドは空でも定義しておく

例題

7-2

(ItemTypeList.java)

(24)

② Java の文法 ( サブクラス )

// 商品種類リスト配列実装クラス

public class ItemTypeArrayList extends ItemTypeList{

private int ARRAY_SIZE = 10;//

配列の大きさ

private ItemType[] itemTypeArray;// 商品種類を保存する配列 // 商品種類を追加するメソッド

public void add(ItemType addItemType){

… }

 …}

ItemTypeList

を継承 することを宣言します

メソッドを実装します

(スーパークラスと同じ

メソッド名にする必要があります)

例題

7-2

(ItemTypeArrayList.java

)

(25)

これでメソッド化できる

引数にスーパークラスを定義すること で、どちらのサブクラスがきても同じ 意味として扱えるので、メソッド化す ることができる

/**

* 商品種類リストの性能を測る

*/

private static void performanceTest(ItemTypeList itemTypeList){

  ・・・・・・

   // 商品種類を 1 万件登録する for(int i=0;i<10000;i++){

itemTypeList.add(new ItemType(1001,"

コーラ ",120));

}

例題

7-2

(ItemTypeList.java)

(26)

③ 抽象クラスとインターフェ イス

public class ItemTypeList { …

//商品種類を表示するメソッド public void display(){

} … }

スーパークラス

public class ItemTypeArrayList extends ItemTypeList{

// 商品種類を表示するメソッド

public void disp

r ay(){

for(int i=0;i<ARRAY_SIZE;i++){

if(itemTypeArray[i] != null){

System.out.println(itemTypeArr…

} } } … }

サブクラス

メソッド名を間違えるとどうなるか

(27)

サブクラスで実装されていな い

サブクラスで実装されていないと、自 動的にスーパークラスのメソッドが実 行されてしまいます

public class ItemTypeList { …

//商品種類を表示するメソッド public void display(){

} …

スーパークラス

ItemTypeList itemTypeList = new ItemTypeArrayList();

//商品種類を追加する

itemTypeList.add(new ItemType(1001,"

コーラ "));

// 商品種類リストを表示する

itemTypeList.display();

サブクラス

public class ItemTypeArrayList extends ItemTypeList{

??

実行!

何もおこらない

(28)

メソッド名の間違いを防ぐ

コンパイルは通り、プログラムは動い てしまうので、バグの発見が大変です

 display()

メソッドはスーパークラスで

は空にしてあるので、必ずサブクラス で実装して欲しいです

サブクラスで実装することを保証する方法があります

(29)

抽象クラス

// 商品種類リストスーパークラス

public class ItemTypeList { …

//商品種類を表示するメソッド public void display(){

} }

// 商品種類リストスーパークラス

public abstract class ItemTypeList { …

// 商品種類を表示するメソッドの定義 public abstract void display();

}

空実装 定義だけする

例題

7-2

(ItemTypeList.java)

例題

7-3

(ItemTypeList.java)

(30)

「定義」と「実装」

public abstract class ItemTypeList { …

//商品種類を表示するメソッドの定義 public abstract void display();

}

スーパークラス

public class ItemTypeArrayList extends ItemTypeList{

// 商品種類を表示するメソッド public void display(){

for(int i=0;i<ARRAY_SIZE;i++){

if(itemTypeArray[i] != null){

System.out.println(itemTypeArr…

} } }

サブクラス

(ItemTypeList.java)

例題

7-3

「定義」ーメソッドを定義する

「実装」ーメソッドを実現する

(31)

定義と実装を分けることの利 点

定義と実装を分けることの利点を考え てみましょう

(32)

目的と手段を分離する

「定義」ーメソッドを定義する(目 的)

「実装」ーメソッドを実現する(手 段)

利用するクラスは「定義」に注目したプログラムが書ける

意味が明確なプログラムが書ける

(33)

抽象クラス

定義ができるのは「抽象クラス」

インスタンス化できないクラス

普通のクラスでは、実装しかできない

public abstract class ItemTypeList { …

//

商品種類を表示するメソッドの定義 public abstract void display();

}

(34)

インターフェイス

 Java

ではメソッドの定義だけする方法 として、インターフェイスが使える

例題

7-4

抽象クラスとほとんど変わりません

抽象クラスとの違いは

変数がもてない

定義しかできない(実装ができない)

(35)

インターフェイスを使う

// 商品種類リスト インターフェイス版

public interface ItemTypeList {

// 商品種類を追加するメソッドの定義

public void add(ItemType addItemType);

}

スーパークラス

// 商品種類リスト配列実装クラス

public class ItemTypeArrayList implements ItemTypeList{

// 商品種類を追加するメソッド

public void add(ItemType addItemType){

//

実装します

サブクラス

インターフェイスは

メソッドが定義と決まっているので

abstract

は書きません

例題

7-4

(ItemTypeList.java)

(36)

④ 抽象クラス

VS インターフェイス

機能で考えた場合どちらでも良い場合 が多い

抽象クラスでは変数や実装ができる

インターフェイスは多重継承ができる

余裕のある人は、意味的な違いを考えてみましょう

(37)

7.2 if 文 vs ポリモーフィズム

 7.2.1

実装クラスの名前を表示する

 7.2.2

どのように実装するか

① if

文で実装する

② インスタンスの違いで分岐する

 7.2.3 if

vs

ポリモーフィズム

(38)

7.2.1

実装クラスの名前を表示した い

 performanceTest

メソッドの始めで、ど の実装クラスなのか表示するようにし ます

/** * 商品種類リストの性能を測る

*/ private static void performanceTest(ItemTypeList itemTypeList){

 

 

//itemTypeList がArrayList なのかLinkedList なのかを表示する

 

long startTime;//

開始時間を保存する long endTime; //終了時間を保存する

  startTime = System.currentTimeMillis();//開始時間を測定する   // 商品種類を 1 万件登録する

(39)

① if 文で実装する

itemTypeList ItemTypeArrayList

インスタンス

ItemTypeLinkedList

インスタンス スーパークラスの変数には

サブクラスを代入できます

逆に、代入してしまうと

どのサブクラスを使っているかは

分からなくなってしまいます

itemTypeList

??

ところが...

(40)

どのインスタンスが

入っているのか調べる方法

instanceof

」演算子を使います

/** * 商品種類リストの性能を測る

*/ private static void performanceTest(ItemTypeList itemTypeList){

//itemTypeList

ArrayList

なのか

LinkedList

なのかを表示する

if(itemTypeList instanceof ItemTypeArrayList){

System.out.println("

実装クラスの名前:

ItemTypeArrayList");

}else if(itemTypeList instanceof ItemTypeLinkedList){

System.out.println("

実装クラスの名前:

ItemTypeLinkedList");

}

} [ [

インスタンス名インスタンス名

] instanceof [ ] instanceof [

クラス名クラス名

] ]

例題

7-6

(Example7_6.java)

(41)

② インスタンスの 違いで分岐する

 if

文がなくても「実装クラスの名前を表 示」はできます

考えてみましょう

(42)

Mai n + mai n( )

I t emTypeLi st + add( )

+ del et e( ) + sear ch( ) + di spl ay( ) + get Name( )

1 2

1 2

I t emTypeLi nkedLi st + add( )

+ del et e( ) + sear ch( ) + di spl ay( ) + get Name( )

I t emTypeAr r ayLi st + add( )

+ del et e( ) + sear ch( ) + di spl ay( ) + get Name( )

クラスにメソッドを加える

実装クラス名を得るメソッドを作りま す

商品種類リストクラスに メソッドを加えます

(43)

インスタンスに場合分けを書 く

// 商品種類リスト 抽象クラス

public abstract class ItemTypeList { ...

//実装クラスの名前を得るメソッド

public abstract String getName();

}

// 商品種類リスト配列実装クラス

public class ItemTypeArrayList extends ItemTypeList{

//実装クラスの名前を得るメソッド public String getName(){

return "ItemTypeArrayList";

} }

// 商品種類リスト連結リスト実装クラス

public class ItemTypeLinkedList extends ItemTypeList{

//実装クラスの名前を得るメソッド public String getName(){

return "ItemTypeLinkedList";

}

スーパークラスで 定義します

サブクラスで実装します

例題

7-6

(ItemTypeList.java)

(ItemTypeArrayList.java)

(44)

インスタンスで場合分けされ る

/** * 商品種類リストの性能を測る

*/ private static void performanceTest(ItemTypeList itemTypeList){

//itemTypeList

ArrayList

なのか

LinkedList

なのかを表示する

System.out.println("

実装クラスの名前: "+itemTypeList.getName());

… }

itemTypeList

に入っているインスタンスによって

例題

7-6

(Example7_6.java)

「ポリモーフィズム」という仕組み

(45)

7.2.3 if 文 VS ポリモーフィ ズム

どちらがよいのか議論してみましょう

(46)

if 文 VS ポリモーフィズム

 if

文は拡張性が低い

要素が増えるたびに

else if

文を追加しなけれ ばならない

ポリモーフィズムなら

Example

を変えないで 実装クラスを追加できる

ポリモーフィズムはクラスが増える

全部の

if

文をポリモーフィズムに直したらク ラスが多くなってよけい理解しにくくなる

バランス

参照

関連したドキュメント

第7回 第8回 第9回 第10回

67 の3−12  令第 59 条の7第5項の規定に基づく特定輸出者の承認内容の変 更の届出は、

第6回赤潮( Skeletonema costatum 、 Mesodinium rubrum 第7回赤潮( Cryptomonadaceae ) 第7回赤潮(Cryptomonadaceae). 第8回赤潮( Thalassiosira

また、特 特定 定切 切盛 盛土 土を を行 行う う場 場合 合に には は、 、一 一般 般承 承継

(第六回~) 一般社団法人 全国清涼飲料連合会 専務理事 小林 富雄 愛知工業大学 経営学部経営学科 教授 清水 きよみ

Study Required Outside Class 第1回..

Study Required Outside Class 第1回..

Study Required Outside Class 第1回..