プログラミング実習Ⅰ

プログラミング実習Ⅰ
第3回
2時限
継承
(教科書8.1)
1
継承とは
あるクラスの属性(フィールド)と機能(メソッド)を,別の
クラスに引き継ぐこと.
教科書の例(8.1節)の場合
Rectangle
# xPosition : int
# yPosition : int
# width : int
(以下,略)
+ getArea() : void
+ setArea() : void
(以下,略)
スーパークラス(親クラス)
継承
Square
# xPosition : int
# yPosition : int
# width : int
(以下,略)
+ getArea() : void
+ setArea() : void
(以下,略)
サブクラス(子クラス)
2
アクセス修飾子 と 継承
アクセス修飾子
UML
public
+
どのクラスからでもアクセス可
protected
#
同じパッケージに属するクラス,および
サブクラスからアクセス可
なし
~
同じパッケージに属するクラスからアク
セス可
private
-
自クラスからアクセス可
privateのフィールド,コンストラクタ,メソッドは継承されない.
3
継承 と 差分プログラミング
第1回の課題1-3のレポート
④ Rectangle.java と Circle.java の共通部分を,tex
ファイルの該当部分に記入する.
共通部分は
• フィールドxPosition, yPosition
※ 前回の課題ではCoordinatesクラスに置き換え
• メソッドmove(int xMove,int yMove)
共通の性質の部分をまとめて,別のクラス(スー
パークラス)にする.
4
スーパークラスFigureの作成
新たなパッケージfigureExを作成する.
次に,前々回の課題で使用した2つのクラス
Rectangle(教科書p.31)
Circle
の共通部分と同じフィールド
• int型 xPosition
• int型 yPosition
および同じメソッド
• void型 move(int xMove, int yMove)
のみを持つFigureクラスをパッケージfigureExに作成
せよ.
5
public class Figure {
protected int xPosition;
protected int yPosition;
赤字の箇所を
修正する.
public Figure(){}
}
public void move(int xMove, int yMove){
(略)
}
6
UMLetでUMLクラス図を書いてみよう
7
Figureクラスを継承するRectangleクラス
public class Rectangle extends Figure {
}
Figure
継承
Rectangle
(略)
スーパークラス
サブクラス
“extends Figure” とつけるだけで,Figureクラスと同じ
フィールド,メソッドを持つことになる.
8
継承をUMLクラス図に書く
フィールド
コンストラクタ,メソッド
Figureクラスを継承 ⇒
Rectangleクラスは,Figureクラスのprivateでないフィールド,
フィールドxPosition, yPositionとprivateでないメソッド
move(int xMove, int yMove)を持つことになる.
RectangleクラスとFigureクラスは「IS-A」関係とも呼ぶ.
A rectangle is a sort of figure.
9
Rectangleクラス固有の
フィールド,メソッドの追加
public class Rectangle extends Figure {
private int width;
private int height;
public Rectangle(int …. 略
}
// コンストラクタ
public void printInfo() {
(略)
}
10
メソッド追加後のUMLクラス図
Rectangleクラスが持つフィールドは
xPosition, yPotision, width, height
コンストラクタは
Rectangle(int xPosition, int yPosition, int width, int height)
メソッドは
move(int xMove, int yMove),
printInfo()
11
Figureクラスを継承するCircleクラス
public class Circle extends Figure {
}
Rectanglesクラスと同様にして,Figureクラスを継承する
Circleクラスを作成し,UMLクラス図も作成する.
Circleクラスが持つフィールドは
xPosition, yPotision, radius
コンストラクタは
Circle(int xPosition, int yPosition, int radius)
メソッドは
move(int xMove, int yMove), printInfo()
12
Circleクラス完成後のUMLクラス図
13
スーパークラスの
コンストラクタ,メソッド呼び出し
オーバーライド
14
スーパークラスのコンストラクタ呼び出し
細かく見ると,クラスRectangleとCircleの共通部分が
他にもある.
Rectangleのコンストラクタ
Circleのコンストラクタ
public Rectangle( …略…){
this.xPosition = …;
this.yPosition = …;
this.width = …;
this.height = …;
}
public Circle( …略…){
this.xPosition = …;
this.yPosition = …;
this.radius = …;
}
共通部分 をスーパークラスのコンストラクタにする.
15
Figureクラスのコンストラクタ呼び出し
Figureのコンストラクタ
public Figure(int xPosition, int yPosition){
this.xPosition = xPosition;
this.yPosition = yPosition;
}
Rectangleのコンストラクタ
public Rectangle(int xPosition, int yPosition, int width, int height){
this.xPosition = xPosition;
this.yPosition = yPosition;
super(xPosition, yPosition);
“super()”でスーパークラス
this.width = width;
(Figure)のコンストラクタを
呼び出す.1行目に記述.
this.height = height;
}
16
Figureのコンストラクタ
public Figure(int xPosition, int yPosition){
this.xPosition = xPosition;
this.yPosition = yPosition;
}
Circleのコンストラクタ
public Circle(int xPosition, int yPosition, int radius){
this.xPosition = xPosition;
this.yPosition = yPosition;
super(xPosition, yPosition);
this.radius = radius;
差分プログラミング: 既存部分
}
を利用し、違う部分を作成する
17
TestFiguresによる動作確認
testDriveパッケージにあるTestFiguresをコピーして,
TestFiguresExクラスを作る.
TestFiguresExクラスの初めにある
import figure.*;
を必ず
import figureEx.*;
に書き換えること.
※ この書き換えをしなければ,figureExパッケージの
動作確認にならない.
18
サブクラスのオブジェクトは,スーパークラスの型で
定義された変数に代入することができる.
- ポリモーフィズムを実現できる.
※ ただし,サブクラスでのみ定義されているメソッド
(ここではprintInfo)は呼び出せない
TestFiguresのmainメソッド
public static void main(String[] args){
Rectangle rectangle1 = new Rectangle(2,1,5,6);
(略)
public static void main(String[] args){
Figure rectangle1 = new Rectangle(2,1,5,6);
(略)
19
スーパークラスのメソッド呼び出し
RectangleのprintInfoメソッド
public void printInfo() {
System.out.printf( "x座標:%d, y座標:%d, 幅:%d, 高さ:
%d¥n", xPosition, yPosition, width, height);
}
CircleのprintInfoメソッド
public void printInfo() {
System.out.printf("x座標:%d, y座標:%d, 半径:%d¥n",
xPosition, yPosition, radius);
}
共通部分 をスーパークラスのメソッドにする.
20
Figureクラスから継承された
メソッドの呼び出し
FigureのprintFigureInfoメソッド
public void printFigureInfo() {
System.out.printf("x座標:%d, y座標:%d, ", xPosition,
yPosition,);
}
RectangleのprintInfoメソッド
public void printInfo() {
printFigureInfo();
System.out.printf("x座標:%d, y座標:%d, 幅:%d, 高さ:
%d¥n", xPosition, yPosition, width, height);
}
21
FigureのprintFigureInfoメソッド
public void printFigureInfo() {
System.out.printf("x座標:%d, y座標:%d, ", xPosition,
yPosition,);
}
CircleのprintInfoメソッド
public void printInfo() {
printFigureInfo();
System.out.printf("x座標:%d, y座標:%d, 半径:%d¥n",
xPosition, yPosition, radius);
}
22
オーバーライド
スーパークラスから継承したメソッドを,(似た内容では
あるが)異なる機能を持つメソッドに再定義できる.
※ オーバーロードとの違いに注意 ・・・
メソッド名が同じで引数が異なるのはオーバーロード.
オーバーライドはあくまでも引数が同じ場合.
23
オーバーライドの利用
オーバーライドをすると,printInfoメソッドの名前を
スーパークラスFigureとサブクラスとで変える必要がなくなる.
public void printFigureInfo() {
public void printInfo() {
System.out.printf("x座標:%d, y座標:%d, ", xPosition,
yPosition);
}
RectangleのprintInfoメソッド
public void printInfo() {
printFigureInfo();
このように変えてしまうと
自分のprintInfoメソッドを指す.
× printInfo();
System.out.printf("幅:%d, 高さ:%d¥n", width, height);
}
24
オーバーライドの利用
オーバーライドをすると,printInfoメソッドの名前を
スーパークラスFigureとサブクラスとで変える必要がなくなる.
public void printFigureInfo() {
public void printInfo() {
System.out.printf("x座標:%d, y座標:%d, ", xPosition,
yPosition);
}
RectangleのprintInfoメソッド
public void printInfo() {
printFigureInfo();
“super”はスーパー
super.printInfo();
クラス(Figure)を指す.
System.out.printf("幅:%d, 高さ:%d¥n", width, height);
}
25
オーバーライドをすると,printInfoメソッドの名前を
スーパークラスFigureとサブクラスとで変える必要がなくなる.
public void printFigureInfo() {
public void printInfo() {
System.out.printf("x座標:%d, y座標:%d, ", xPosition,
yPosition);
}
CircleのprintInfoメソッド
public void printInfo() {
printFigureInfo();
“super”はスーパー
super.printInfo();
クラス(Figure)を指す.
System.out.printf("半径:%d¥n", radius);
}
26
現時点のUMLクラス図
27
Figuresクラスでの
Coordinatesクラスの利用
前回,Rectangle, Circleクラスの
フィールドxPositionとyPositionをCoordinatesクラスに
置き換え
をした.今回も同じことをする.
フィールドxPositionとyPositionとそれに関するメソッドは
Figureクラスに移されたので,この作業はFigureクラスのみ
での作業になる.
28
委譲
フィールド変数として他クラスの参照型変数を持ち,
あるメソッドの処理をその他クラスに依頼すること.
今回のCoordinatesクラス
Figure
# coordinates : Coordinates
+ move(xMove: int, yMove: int) : void
(以下,略)
委譲(コンポジション)
Coordinates
座標に関する処理を
- xPosition : int
Coordinatesクラスに依頼 - yPosition : int
+ move(xMove: int, yMove: int) : void
29
(以下,略)
委譲をUMLクラス図に書く
継承の「IS-A」関係に対し,委譲は「HAS-A」関係と呼ぶ.
FigureクラスとCoordinatesクラスは「HAS-A」関係.
A figure has a “coordinates.”
30
Coordinatesクラス委譲後の
全体のUMLクラス図
31
課題3-1
Rectangle クラスと Circle クラスの両方に,以下のメソッドを
追加せよ.
void型 flip( ):
長方形または円を,y = x に関して線対称移動する.
具体的には,以下のようにすればよい.
長方形の場合: x座標とy座標を入れ
y
かえ,幅と高さを入れかえる.
円の場合: x座標とy座標を入れかえる
のみ.
y=x
※ 必要に応じて,他クラスにもメソッドを
追加したり,オーバーライドを利用せよ.
32
x
課題3-1のUMLクラス図
プログラムを書く前に,まずクラス図を書き換える.
必要なメソッドがあれば各自で追加
必要とは
限らない
33
課題3-1のテストについて
各自でTestFiguresExクラスを修正して,動作確認する.
以下はあくまでも実行例である.
x座標: 2, y座標: 1, 幅: 5, 高さ: 6
x座標: 4, y座標: 3, 幅: 5, 高さ: 6
x座標: 3, y座標: 4, 幅: 6, 高さ: 5
x座標: 4, y座標: 2, 半径: 2
x座標: 7, y座標: 5, 半径: 2
x座標: 5, y座標: 7, 半径: 2
34
予習確認テストの予告
次回2時限の開始時,教科書の以下の範囲の筆記試
験を行うので,各自予習をしておくこと.
抽象メソッド,抽象クラス
(教科書
8.2節 pp.187-196)
35