オブジェクト指向 プログラミング演習sun.ac.jp/prof/yamagu/2019oop/oop02.pdf ·...
TRANSCRIPT
オブジェクト指向プログラミング演習
第2回 クラス・インスタンス・メソッド・フィールド・コンストラクタ
2019.04.18
ICPC の宣伝
国際大学対抗プログラミングコンテスト
⚫ 3人一組のチームでプログラムを書く速さを競う
◆国内予選:ネットワーク上で 6月末~7月頭
◆アジア地区予選:日本国内で秋に開催
◆世界大会:2020年は6月にモスクワで
⚫ 参加登録締切:国内予選の2~3週間前
⚫ “ICPC” で検索
今年は7月12日
今年は11月に横浜で
先週の話
⚫ モジュール化
◆大きなプログラムは部品に分けて考える
2019.04.18
部品を考えるときのコツ
⚫ あたりまえのことを意識する
◆言葉にしておく
◆ちょうどよい言葉を見つける努力をする
⚫ 「それってどういうこと?」を説明する
◆どういうモノ/作業なのかを具体的に考える
➡ 部品に分かれていく
◆便利な言葉を使わない
◼「処理」「管理」「活用」などの言葉を使うと、具体性がなくなる
2019.04.18
「部品に分ける」から「プログラミング」へ
部品に分けて考えたら、それぞれの部品をプログラムで書く
⚫ 用意されている部品を組み合わせて部品を作る
⚫ 自分で作る部品の一つ一つはデータと手順
◆オブジェクト指向では、これをひとまとまりの「クラス」として表現する
◆クラスはモノの種類を表すと考える
◆クラスの中身には、次のものを宣言する:
◼データを表すフィールド
◼手順を表すメソッド
⚫ 全体を表すクラスも必要 2019.04.18
オブジェクト指向は、ものごとを整理する方法
整理するための記述が、冗長に思えるかも
⚫ もっと短く書けるのに…
オブジェクト指向が威力を発揮するのは、ある程度以上に大きなプログラムの開発
2019.04.18
今日のお題
⚫ クラス
⚫ インスタンス
⚫ メソッド
⚫ フィールド
⚫ コンストラクタ
➡ Java での書き方を学ぶ
2019.04.18
モノの種類オブジェクト
モノの実体関数のようなもの。モノの機能を表す計算手順
新しいインスタンスを作ったときに呼び出される計算手順
クラスごとに宣言されるデータの記憶場所。変数のようなもの。インスタンスごとに別の値を憶えることができる。
2019.04.18
Javaでの書き方を解説しますが…
⚫ Javaにはさまざまなキーワードがある
◆一気に全部解説すると、混乱しそう…
⚫ 書き方を例を挙げて解説します
◆いくつかのキーワードについては、「そういう書き方をするもの」と覚えてください
◼あとの授業で解説するかも知れません
Javaのソースコード
⚫ クラスの宣言を(一つ以上)並べて書く
◆この他に、次のものを書くこともある:
◼用意されたクラスを使用する宣言
◼パッケージ名の宣言(第13回で話す予定)
⚫ クラスの中に一つだけ、public というキーワードを付ける。
◆ public なクラスの名前は、ファイル名と同じでなければならない
2019.04.18
2019.04.18
Javaにおけるクラスの宣言
class クラス名 {
クラスの中身
}
⚫ class は宣言のためのキーワード
⚫ クラス名は、自由につけてよい。
◆英字で始まる英数字列を勧める
◆先頭を大文字にする習慣がある
⚫ クラスの中身はフィールドの宣言とメソッドの宣言
Javaにおけるフィールドの宣言
型 フィールド名;
⚫ 型は、プリミティブ型またはクラス名
◆プリミティブ型は、int, char, double など
⚫ 宣言の最後に ;(セミコロン)を書く
◆フィールド名をカンマで区切って並べてもよい
⚫ フィールド名は、自由につけてよい。
◆英字で始まる英数字列を勧める
⚫ フィールドには、その型の値(インスタンス)を一つ記憶させておくことができる。
◆変数みたいなもの 2019.04.18
2019.04.18
Javaにおけるメソッドの宣言
返戻値の型 メソッド名(仮引数列) {
メソッドの中身
}
⚫ メソッド名は自由につけてよい。
◆英字で始まる英数字の列を勧める
⚫ 返戻値の型は、プリミティブ型、クラス名またはvoid
(void は返戻値がないことを表す)
⚫ 仮引数が無いときは、仮引数列に何も書かない
◆仮引数が無いときも、括弧()は書く。
⚫ C言語における関数の宣言とよく似ている
◆メソッドの中身は、変数の宣言と命令文の並び
Javaの実行の起点
C言語では、main関数が実行の起点
Java では、mainメソッドが実行の起点
⚫ 実行の起点になるmainメソッドは、次のように宣言しなければならない:
public static void main(String args[]) {
mainメソッドの中身
}
⚫ public や static はメソッドの宣言に付けたキーワード
⚫ mainの引数は文字列(String)の配列。上記のargsはこれを受け取る仮引数名なので、別の名前にしてもよい。
2019.04.18
とりあえず、動くプログラム例
public class Hello {
public static void main(String args[]) {
System.out.println("Hello");
}
}
2019.04.18
Hello.java
⚫ 宣言されているクラスは Hello だけ
◆ Helloクラスは public。ファイル名も Hello.java
⚫ Helloクラスで宣言されているメソッドはmainだけ
⚫ mainの中で実行される命令は System.out.println("Hello");だけ
◆ System.out.printlnは、引数に与えられたものをターミナルに表示する命令 ちょっと長いが、よく
使うので覚えておこう
小文字のエル
ぜんぜんオブジェクト指向
らしくないプログラム
Javaのコンパイルと実行
⚫ 前ページの Hello.java というファイルを作る
⚫ コンパイル
$ javac Hello.java
⚫ 実行
$ java Hello
2019.04.18
Hello.class というファイルが作られる
実行されて、ターミナル上にHelloと表示される
例)三角形の面積を求める
xy平面上の3点の座標を入力すると、それらの点を頂点とする三角形の面積を出力するプログラムを書こう
このプログラムに登場するモノは?
…三角形
⚫ 三角形は、3つの頂点でできている
⚫ 一つの頂点は、座標(二つの値)でできている
計算の方法は?
…3辺の長さとヘロンの公式で求まる
⚫ 辺の長さは頂点間の距離 2019.04.18
(使えそうな)用意された部品
⚫ Scanner
◆入力を解釈して値を返すモノ
◆import しないと使えない
◼java.util.Scanner
◆作るには入力元の情報が必要
◼ターミナルからの入力は System.in
⚫ Math.sqrt
◆sqrtは平方根を計算する
◆java.lang.Math クラスのメソッド
◆java.lang の下のクラスは import せずに使える
⚫ System.out.println 2019.04.18
用意された部品の一覧
Java API リファレンス
で検索
※)APIとは、プログラムの部品の使い方
(Application Programming Interface)
2019.04.18
クラス・インスタンス・メソッド
⚫ モノの性質や機能はモノの種類ごとに決まる◆クラス(モノの種類)を定義することがプログラミング
◆二種類の部品
◼そのモノを構成する部品であるモノ
◼そのモノに関する手順の部品である手順
⚫ インスタンスの部品◆他のインスタンス
◼モノ(インスタンス)は、そのモノを表す変数やフィールドで表現される
⚫ メソッドの部品◆部品であるメソッドの呼出し 2019.04.11
再掲
モノを表すために必要な情報は何か
⚫ 三角形は3つの頂点でできている
◆三角形を表すには、頂点の情報が3つ必要
…三角形を表すクラスの中で、頂点を表すフィールドを3つ宣言する
⚫ 頂点はx座標とy座標の値で決まる
◆頂点を表すには、二つの値が必要
…頂点を表すクラスの中で、値を表すフィールドを二つ宣言する
2019.04.18
フィールドを宣言する部分のコード
2019.04.18
public class Sankaku {
Choten v0,v1,v2;
}
class Choten {
double x,y;
}
三角形を表すクラス Sankaku
• 頂点を三つ持つ• それぞれの頂点にv0,v1,v2
と名前を付けた
頂点を表すクラス Choten
• 座標値を二つ持つ• フィールド名は、それぞれ x と y
• どちらの座標値も double で表す
Sankaku.java
手順(計算)に必要な情報は何か?
⚫ 三角形が決まれば、面積も決まる
◆すでに決まっている三角形に対して、面積を問い合わせると考えれば、追加で必要な情報はない。
…引数なし
⚫ 頂点間の距離を求めるには、二つの頂点が決まる必要がある
◆すでに決まっている頂点に対して、別の頂点までの距離を問い合わせると考えると、もう一つの頂点の情報が必要
…引数として頂点を一つ受け渡しする2019.04.18
2019.04.18
メソッドやフィールドの参照
クラスを型とする変数やフィールドはインスタンスを表す。
そのインスタンスのメソッドやフィールドを参照するには、.(ピリオド)を使う。
例)
⚫ Sankaku のフィールド v0 は Choten のインスタンス
⚫ v0は頂点を表すので、x座標とy座標を持つ
◆頂点v0のx座標は v0.x, y座標は v0.y と書く
⚫ クラスChotenでメソッドkyoriが定義されるなら、v0についてのkyoriの呼出しは、v0.kyori(実引数列)と書く。
面積を求めるメソッドのコード
2019.04.18
public class Sankaku {
Choten v0,v1,v2;
double menseki() {
double a = v0.kyori(v1);
double b = v1.kyori(v2);
double c = v2.kyori(v0);
double s = (a+b+c)/2;
return Math.sqrt(s*(s-a)*(s-b)*(s-c));
}
}
class Choten {
double x,y;
double kyori(Choten c) {
double dx = x-c.x;
double dy = y-c.y;
return Math.sqrt(dx*dx+dy*dy);
}
}
インスタンスの生成
インスタンスを生成する式を次のように書く:
new クラス名(実引数列)
⚫ これは、指定したクラスのインスタンスを返す式なので、たいていは、この式の値を変数やフィールドに代入する。
例) Scanner sc = new Scanner(System.in);
⚫ 引数は、コンストラクタ(後述)に渡される
2019.04.18
コンストラクタのコード
2019.04.18
public class Sankaku {
…
Sankaku(Choten p0, Choten p1, Choten p2) {
v0=p0; v1=p1; v2=p2;
}
}
class Choten {
…
Choten(double x, double y) {
this.x=x; this.y=y;
}
}
モノを作る =
そのモノを表すのに必要な情報を保持する(コピーする)
…初期化のためのメソッド(コンストラクタ)を書く
thisは「このインスタンス」を表す。あいまいにならない限り省略可能。ここではフィールドと仮引数に同じ名前を使ったので、区別するためにフィールドにはthisをつける必要がある。
コンストラクタは、クラス名(仮引数列){
コンストラクタの中身}
で宣言する
処理の全体像:mainでやること
2019.04.18
import java.util.Scanner;
public class Sankaku {
…
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
Choten p[] = new Choten[3];
for(int i=0 ; i<3 ; i++) {
double x = sc.nextDouble();
double y = sc.nextDouble();
p[i] = new Choten(x,y);
}
Sankaku t = new Sankaku(p[0],p[1],p[2]);
double m = t.menseki();
System.out.println(m);
}
}
Scanner を用意する
3頂点の座標を入力する
三角形を作る
面積を求めて表示する
次回予告
⚫継承
⚫オーバーライド
⚫インタフェース
2019.04.18