アルゴリズムとプログラミング (Algorithms and Programming)

33
アアアアアアアアアアアアアア (Algorithms and Programming) アア アアアアア 11: •アアアアアextends アアアアア アアアアアアア •アアアアアアアアアアアアアアア アアア •アアアアア (abstract アアアアア ) アアアアアhttp://www.pe.titech.ac.jp/~watanabe/lecture/ap/index-j.html

description

アルゴリズムとプログラミング (Algorithms and Programming). 継承の実装:  extends キーワード           コンストラクタ 継承とメソッドのオーバーライド,可視性 抽象クラス (abstract キーワード ). 第11回:継承の実装. 講義資料等:. http://www.pe.titech.ac.jp/~watanabe/lecture/ap/index-j.html. 継承の実装. スーパークラス. Vehicle ( 乗り物 ). - speed: double. - PowerPoint PPT Presentation

Transcript of アルゴリズムとプログラミング (Algorithms and Programming)

Page 1: アルゴリズムとプログラミング (Algorithms and Programming)

アルゴリズムとプログラミング

(Algorithms and Programming)

第11回:継承の実装

•継承の実装:  extends キーワード          コンストラクタ•継承とメソッドのオーバーライド,可視性•抽象クラス (abstract キーワード )

•継承の実装:  extends キーワード          コンストラクタ•継承とメソッドのオーバーライド,可視性•抽象クラス (abstract キーワード )講義資料等: http://www.pe.titech.ac.jp/~watanabe/lecture/ap/index-j.html

Page 2: アルゴリズムとプログラミング (Algorithms and Programming)

継承の実装Vehicle( 乗り物 )- speed: double

# changeSpeed(s:double)# getSpeed(): double

Plane- altitude: double

# takeOff ()# land ()

サブクラスは、スーパークラスの全てのフィールドとメソッドを含んでいる。(実際にアクセスできるかは、アクセス修飾子に従う)

サブクラスは、スーパークラスの全てのフィールドとメソッドを含んでいる。(実際にアクセスできるかは、アクセス修飾子に従う)

スーパークラス

サブクラス

Page 3: アルゴリズムとプログラミング (Algorithms and Programming)

継承の実装: extends キーワード

Vehicle( 乗り物 )- speed: double

# changeSpeed(s:double)# getSpeed(): double

Plane- altitude: double

# takeOff ()# land ()

class Plane extends Vehicle {

private double altitude;

protected void takeOff() {

処理 ( スーパークラスのメソッドも呼べる );

}

protected void land() {

処理 ;

}

}

class Plane extends Vehicle {

private double altitude;

protected void takeOff() {

処理 ( スーパークラスのメソッドも呼べる );

}

protected void land() {

処理 ;

}

}

スーパークラス

サブクラス

Page 4: アルゴリズムとプログラミング (Algorithms and Programming)

スーパークラスへのアクセスVehicle( 乗り物 )- speed: double

# changeSpeed(s:double)# getSpeed(): double

Plane- altitude: double

# takeOff ()# land ()

public static void main( 略 ) {

Plane o = new Plane();

o.changeSpeed(0.0);

for(int i=0;i<=300;i+=50){

o.changeSpeed(i);

o.takeOff();

}

System.out.println(" 離陸! ");

}

}

public static void main( 略 ) {

Plane o = new Plane();

o.changeSpeed(0.0);

for(int i=0;i<=300;i+=50){

o.changeSpeed(i);

o.takeOff();

}

System.out.println(" 離陸! ");

}

}

スーパークラス

サブクラス

Page 5: アルゴリズムとプログラミング (Algorithms and Programming)

全てのクラスのスーパークラスObjectクラスextends キーワードが無い全てのクラスは、自動的に Objectクラスのサブクラスとなる。従って、全てのクラスは Object クラスのフィールドとメソッドを暗黙的に継承している。

extends キーワードが無い全てのクラスは、自動的に Objectクラスのサブクラスとなる。従って、全てのクラスは Object クラスのフィールドとメソッドを暗黙的に継承している。

Vehicle( 乗り物 )- speed: double

# changeSpeed(s:double)# getSpeed(): double

Plane- altitude: double

# takeOff ()# land ()

Objectクラス

Page 6: アルゴリズムとプログラミング (Algorithms and Programming)

継承とコンストラクタ

サブクラスのコンストラクタを呼び出すと..

1.まずスーパクラスのコンストラクタが実行される(何も指定しなければデフォルトコンストラクタが呼ばれる.引数は無し)

2.次にサブクラスのコンストラクタが実行される

Page 7: アルゴリズムとプログラミング (Algorithms and Programming)

class X {

int x;

X() {

x = 100;

}

}

class Y extends X {

int y;

Y() {

y = 200;

}

}

class X {

int x;

X() {

x = 100;

}

}

class Y extends X {

int y;

Y() {

y = 200;

}

}

サブクラスのコンストラクタ( 例 )SampleAP0901.java

ここに super(); が省略されていると考える

Page 8: アルゴリズムとプログラミング (Algorithms and Programming)

class SampleAP0901 {

public static void main(String[] args) {

Y o = new Y();

System.out.println("x= " + o.x );

System.out.println("y= " + o.y );

}

}

class SampleAP0901 {

public static void main(String[] args) {

Y o = new Y();

System.out.println("x= " + o.x );

System.out.println("y= " + o.y );

}

}

サンプルプログラム ( 続き )SampleAP0901.java続き

実行結果

x= 100

y= 200

Page 9: アルゴリズムとプログラミング (Algorithms and Programming)

親のコンストラクタを指定する場合

Superキーワード

class X { int x; X(int a) { x = a; }}class Y extends X { int y; Y(int a, int b) { super(a);   y = b; }}

class X { int x; X(int a) { x = a; }}class Y extends X { int y; Y(int a, int b) { super(a);   y = b; }}

SampleAP0902.java

コンストラクタで superを使うときは最初の行でしか使えない!コンストラクタで superを使うときは最初の行でしか使えない!

( this キーワードとの併用は不可)

Page 10: アルゴリズムとプログラミング (Algorithms and Programming)

class SampleAP0902 {

public static void main(String[] args) {

Y o = new Y( 1, 2 );

System.out.println("x= " + o.x );

System.out.println("y= " + o.y );

}

}

class SampleAP0902 {

public static void main(String[] args) {

Y o = new Y( 1, 2 );

System.out.println("x= " + o.x );

System.out.println("y= " + o.y );

}

}

SampleAP0902.java続き

実行結果

x= 1

y= 2

Page 11: アルゴリズムとプログラミング (Algorithms and Programming)

class X {

int x;

X() {

x = 100;

}

}

class Y extends X {

int y;

Y() {

y = 200;

}

}

class X {

int x;

X() {

x = 100;

}

}

class Y extends X {

int y;

Y() {

y = 200;

}

}

SampleAP0901.java(再)

ここに super(); が省略されていると考える

暗黙の親コンストラクタ呼び出し

Page 12: アルゴリズムとプログラミング (Algorithms and Programming)

継承を禁止する final キーワード

final class X {

int x;

}

class Y extends X {

int y;

}

final class X {

int x;

}

class Y extends X {

int y;

}

サブクラスの宣言を禁止!

コンパイルエラー!

final 宣言したクラスは、 extendsでサブクラスを作ることが禁止される

Page 13: アルゴリズムとプログラミング (Algorithms and Programming)

メソッドのオーバーライドオーバーライド (override)

親クラスと子クラスのそれぞれに、メソッド名、引数、戻り値が全て同一で内容が異なるメソッドを定義すること

ひとつのクラス内に、メソッド名が同じで、引数の型及び数が異なるメソッドを定義すること

混同注意!オーバーロード (overload)既出

Page 14: アルゴリズムとプログラミング (Algorithms and Programming)

オーバーライドの目的Vehicle( エンジン付き乗り物 )

- speed: double

# getSpeed(): double# startEngine ()

Plane

- altitude: double

# takeOff ()# startEngine ()

もともと、サブクラスにはスーパークラスのフィールドとメソッドが全て自動的に引き継がれている。

しかし、引き継がれているメソッドの処理内容を、サブクラスで再定義 ( 変更 )したい場合がある 。

オーバーライドの必要性

Page 15: アルゴリズムとプログラミング (Algorithms and Programming)

オーバーライドと可視性

子クラスでオーバーライドするメソッドの可視性は、親クラスのメソッドの可視性により制限される

オーバーライドされるスーパークラスのメソッドに指定されている修飾子

オーバーライドするサブクラスのメソッド

public public 指定が必要protected protected か public が必要private アクセス不可につき、オーバーライド

不可無指定 private 指定は不可

親クラスで protected が指定されているメソッドを子クラスでオーバーライドするには protected か public 指定が必要

Page 16: アルゴリズムとプログラミング (Algorithms and Programming)

親・子クラスにおけるオブジェクト参照型変数の互換

性Java のきまり:

•子クラスのインスタンスを指すオブジェクト参照型変数を、親クラスの参照変数に代入することができる。

•代入後も、インスタンスの出身が子クラスであることを忘れずに記憶しておく仕組みになっている。

•子クラスのインスタンスを指すオブジェクト参照型変数を、親クラスの参照変数に代入することができる。

•代入後も、インスタンスの出身が子クラスであることを忘れずに記憶しておく仕組みになっている。

型の違いに厳しい Java ですが..

1つのオブジェクトが、あたかも複数の型を持つかのように見せることができる。

Page 17: アルゴリズムとプログラミング (Algorithms and Programming)

(メソッドのオーバーライドと参照型変数の互換性によって実現される)

ジェット機

乗り物

自動車飛行機

プロペラ機

ジェット機は飛行機でもあり、乗り物で

もある

ジェット機は飛行機でもあり、乗り物で

もある

ジェット機クラスのインスタンスを、乗り物オブジェクトとして扱うことができる。

ジェット機クラスのインスタンスを、乗り物オブジェクトとして扱うことができる。

ジェット機クラスのインスタンスに対する操作を、乗り物に対する操作として記述できる

ジェット機クラスのインスタンスに対する操作を、乗り物に対する操作として記述できる

このような記述の仕方にどんなメリットがあるの?

(再)オブジェクト指向3原則:ポリモーフィズム

Page 18: アルゴリズムとプログラミング (Algorithms and Programming)

乗り物

# 動力を始動する ()

飛行機

# 動力を始動する ()

自動車

# 動力を始動する ()

ジェット機

# 動力を始動する ()

プロペラ機

# 動力を始動する ()

操作名は同じだが、実際の操作内容はそれぞれ異なる

操作名は同じだが、実際の操作内容はそれぞれ異なる

メソッドのオーバーライド

Page 19: アルゴリズムとプログラミング (Algorithms and Programming)

ジェット機クラスのインスタンスを生成する

:ジェット機

このインスタンスを乗り物オブジェクトと見なす(乗り物オブジェクト変数 v1 に格納する)

v1. 動力を始動する ()

動力を始動する () メッセージを送るこの記法は、ジェット機に限らず、プロペラ機にも自動車にも、将来的に追加される乗り物にもそのまま変更なく使える。上位概念(スーパークラス)オブジェクトに対する

操作として記述しておくと、サブクラスの細かい修正や追加などに対して強いプログラムになる(保守性が高い)

乗り物オブジェクトの操作が呼び出されるように記述されているが、自動的にジェット機オブジェクトに対する操作が呼び出される

乗り物 v1 = new ジェット機 ();

new ジェット機 ();

ジェット機クラスのインスタンスへの参照乗り物クラス

Page 20: アルゴリズムとプログラミング (Algorithms and Programming)

ジェット機クラスのインスタンスを生成する

:ジェット機

このインスタンスをジェット機オブジェクト変数 j1 に格納する

j 1 . 動力を始動する ()

動力を始動する () メッセージを送る

この記法では、プロペラ機や自動車に変更したり、さらには将来的に追加される乗り物に対しては、そのままでは使えない。プログラムの記述を変更する必要がある!

new ジェット機 ();

ジェット機 j1 = new ジェット機 ();

ジェット機クラスのインスタンスへの参照ジェット機クラス

Page 21: アルゴリズムとプログラミング (Algorithms and Programming)

その効果:  サブクラスの細かい修正や追加などに対して強い(保守性が高い)プログラムになる

ポリモーフィズム (polymorphism) の意味:  1つのオブジェクトが複数の型を持つ ← 継承により実現ポリモーフィズムの活用の仕方:  上位概念(スーパークラス)への操作としてプログラムを記述する

ポリモーフィズムの意味と効果

オブジェクト指向プログラミングの有効性!

Page 22: アルゴリズムとプログラミング (Algorithms and Programming)

class X { // スーパー(親)クラス int x;

}

class Y extends X { // サブ(子)クラス int y;

}

class SampleAP1001 {

public static void main(String[] args){

X o = new Y();// サブクラス Y のインスタンスを親クラス X

} // の参照型変数へ代入できる!}

class X { // スーパー(親)クラス int x;

}

class Y extends X { // サブ(子)クラス int y;

}

class SampleAP1001 {

public static void main(String[] args){

X o = new Y();// サブクラス Y のインスタンスを親クラス X

} // の参照型変数へ代入できる!}

参照型変数への代入 ( 例 )SampleAP1001.java

Page 23: アルゴリズムとプログラミング (Algorithms and Programming)

class Shape { // 2次元図形の面積を表現するクラス double a; // 一般に、面積を計算するには、縦 × 横や底辺 × 高さ/2など、

double b; // 2つの辺の長さを与える必要があると考え、変数を2つ用意する

Shape(double x, double y) { a = x; b = y; }

double getArea() { // ここでは具体的な定義を与えないことにする。

return 0.0; // 具体的な定義はサブクラスで与える。

}

}

class Shape { // 2次元図形の面積を表現するクラス double a; // 一般に、面積を計算するには、縦 × 横や底辺 × 高さ/2など、

double b; // 2つの辺の長さを与える必要があると考え、変数を2つ用意する

Shape(double x, double y) { a = x; b = y; }

double getArea() { // ここでは具体的な定義を与えないことにする。

return 0.0; // 具体的な定義はサブクラスで与える。

}

}

メソッドのオーバーライド ( 例 )SampleAP1002.java

Page 24: アルゴリズムとプログラミング (Algorithms and Programming)

class Triangle extends Shape { // 三角形 Triangle(double x, double y); super(x,y); // x,y としては底辺と高さを与え

る } double getArea() { return ( a * b / 2 ); }}class Rectangle extends Shape { // 四角形 Rectangle (double x, double y){ super(x,y); //x,y としては各辺の長さを与える } double getArea() { return ( a * b ); }}

class Triangle extends Shape { // 三角形 Triangle(double x, double y); super(x,y); // x,y としては底辺と高さを与え

る } double getArea() { return ( a * b / 2 ); }}class Rectangle extends Shape { // 四角形 Rectangle (double x, double y){ super(x,y); //x,y としては各辺の長さを与える } double getArea() { return ( a * b ); }}

SampleAP1002.java続き

オーバーライド

オーバーライド

Page 25: アルゴリズムとプログラミング (Algorithms and Programming)

class SampleAP1002 { public static void main(String[] args) {

Shape o1 = new Shape( 10.0, 10.0 ); Shape o2 = new Triangle( 10.0, 10.0 ); Shape o3 = new Rectangle( 10.0, 10.0 );

System.out.println("o1 の面積は " + o1.getArea() ); System.out.println("o2 の面積は " + o2.getArea() ); System.out.println("o3 の面積は " + o3.getArea() ); }}

class SampleAP1002 { public static void main(String[] args) {

Shape o1 = new Shape( 10.0, 10.0 ); Shape o2 = new Triangle( 10.0, 10.0 ); Shape o3 = new Rectangle( 10.0, 10.0 );

System.out.println("o1 の面積は " + o1.getArea() ); System.out.println("o2 の面積は " + o2.getArea() ); System.out.println("o3 の面積は " + o3.getArea() ); }}

SampleAP1002.java続き

Page 26: アルゴリズムとプログラミング (Algorithms and Programming)

o1 の面積は 0.0o2 の面積は 50.0o3 の面積は 100.0

o1 の面積は 0.0o2 の面積は 50.0o3 の面積は 100.0

実行結果

引数に与えた数値は o1 ~ o2まで全て同じだが、それぞれオーバーライドされた getArea() メソッドが、異なる処理を実行している。

Page 27: アルゴリズムとプログラミング (Algorithms and Programming)

抽象クラス: 抽象メソッドを持つためオブジェクト生成できないクラス

乗り物- スピード# スピードを変える ()# スピードを表示する ()

飛行機- 高度

# 離陸する ()# 着陸する ()# 高度を表示する ()

飛行機クラスでは、依然としてスピードを表示する () 操作は必須であり、乗り物クラスは使われる。

飛行機クラスでは、依然としてスピードを表示する () 操作は必須であり、乗り物クラスは使われる。

クラス名をイタリックにすると抽象クラス

クラス名をイタリックにすると抽象クラス

乗り物クラスのインスタンスは存在しないことが保証される

乗り物クラスのインスタンスは存在しないことが保証される

Page 28: アルゴリズムとプログラミング (Algorithms and Programming)

抽象クラスの実装

親クラスではメソッド名だけ定義して、子クラスにおいて、オーバーライドにより具体的な処理内容を記述する

親クラスではメソッド名だけ定義して、子クラスにおいて、オーバーライドにより具体的な処理内容を記述する

抽象メソッド: abstract キーワード具体的な処理内容が与えられていないため、インスタンスの作成は不可

Page 29: アルゴリズムとプログラミング (Algorithms and Programming)

abstract class Shape { // 抽象クラス double a; double b;

Shape(double x, double y) { a = x; b = y; } // 抽象メソッドとして定義(この方が自然) abstract double getArea();

}

abstract class Shape { // 抽象クラス double a; double b;

Shape(double x, double y) { a = x; b = y; } // 抽象メソッドとして定義(この方が自然) abstract double getArea();

}

SampleAP1003.java

抽象クラスの使用例

•抽象メソッドが1つでもあるとそのクラスは抽象クラス→サブクラスで具体的な処理内容を与えて使用する

•抽象クラスだからといって、全てが抽象クラスである必要は無い

Page 30: アルゴリズムとプログラミング (Algorithms and Programming)

class Triangle extends Shape { // 三角形 Triangle(double x, double y); super(x,y); // x,y としては底辺と高さを与え

る } double getArea() { return ( a * b / 2 ); }}class Rectangle extends Shape { // 四角形 Rectangle (double x, double y){ super(x,y); //x,y としては各辺の長さを与える } double getArea() { return ( a * b ); }}

class Triangle extends Shape { // 三角形 Triangle(double x, double y); super(x,y); // x,y としては底辺と高さを与え

る } double getArea() { return ( a * b / 2 ); }}class Rectangle extends Shape { // 四角形 Rectangle (double x, double y){ super(x,y); //x,y としては各辺の長さを与える } double getArea() { return ( a * b ); }}

この部分は SampleAP1002.javaと同じSampleAP1003.java続き

Page 31: アルゴリズムとプログラミング (Algorithms and Programming)

class SampleAP1003 { public static void main(String[] args) {

Shape o2 = new Triangle( 10.0, 10.0 ); Shape o3 = new Rectangle( 10.0, 10.0 );

System.out.println("o2 の面積は " + o2.getArea() ); System.out.println("o3 の面積は " + o3.getArea() ); }}

class SampleAP1003 { public static void main(String[] args) {

Shape o2 = new Triangle( 10.0, 10.0 ); Shape o3 = new Rectangle( 10.0, 10.0 );

System.out.println("o2 の面積は " + o2.getArea() ); System.out.println("o3 の面積は " + o3.getArea() ); }}

SampleAP1003.java続き

抽象クラスのインスタンス化を削除

Page 32: アルゴリズムとプログラミング (Algorithms and Programming)

まとめ1

•継承の実装:  extends キーワード•継承とコンストラクタ : super キーワード•継承の禁止:  final キーワード

•継承の実装:  extends キーワード•継承とコンストラクタ : super キーワード•継承の禁止:  final キーワード

Page 33: アルゴリズムとプログラミング (Algorithms and Programming)

まとめ2

•継承とメソッドのオーバーライド•抽象メソッド、抽象クラス

より保守性の高いプログラムの実現

•継承とメソッドのオーバーライド•抽象メソッド、抽象クラス

より保守性の高いプログラムの実現

世の中で既に作成され公開されている各種の Javaクラスライブラリはこのような考え方で作成されている。適当なクラスを継承してカスタマイズすることにより、極めて簡単に自分独自の問題を解決することができる。