ソフトウェア開発実践セミナー
「早勝ち数当てゲーム」で対戦しよう
∼二分探索では当たりません∼
土村 展之 [email protected] 金子 勇 [email protected] http://www.misojiro.t.u-tokyo.ac.jp/˜tutimura/sem3/ 情報理工学系研究科 数理情報学専攻セミナーの構成
「 早 勝 ち 数 当 て ゲ ー ム 」を 題 材 に プ ロ グ ラ ム を 作 る 日時 担当 回 内容 10/16 両方 1. 概要説明,演習準備(アカウント確認) 10/23 土村 2. プログラムの書き方(作法,標準入出力など) 10/30 土村 3. (演) サーバ処理部を作成 11/ 6 金子 4. ネットワークの基礎,UNIX + C での socket の使い方 11/13 金子 5. (演) C 言語によるサーバ−クライアントシステムの構築 11/20 土村 6. http, CGI や Perl による組み合わせ 11/27 土村 7. (演) Perl によるサーバ−クライアントシステムの構築 12/ 4 金子 8. Windows プログラミングと Winsock による通信 12/11 土村 9. オブジェクト指向のお作法と JAVA の初歩 12/18 土村 10. (演) JAVA によるクライアント作成 未定 金子 11. プログラムの高速化とシステムの理解 未定 金子 12. (演) 高速化やシステムプログラミングの演習オブジェクト指向
(Object Oriented)
• 今やプログラミング上なくてはならない概念 (かつての構造化プログラミングのよう) • プログラムのモジュール化を進め、再利用を容易に • しかし万能でもない ・ クラス設計の難しさ ・ 題材による向き・不向き • オブジェクト指向言語⇐⇒
手続き型言語(?) • デスクトップのアイコン操作と類似オブジェクト指向言語
•
Smalltalk
(オブジェクト指向言語として完成) •C++, Objective-C, Object Pascal, Java, C#
•Perl, Ruby, Python, JavaScript
•
Object Oriented Fortran, Object Oriented COBOL,
Common Lisp Object System
オブジェクト指向的コード例
目標「
100
個の日付を扱う」非オブジェクト指向的
int year[100], month[100], day[100];
...
date_print(year[6], month[6], day[6]);
オブジェクト指向的
struct date_st {
int year, month, day;
};
オブジェクト指向のプログラム設計
• 変数と関数を合わせたもの(クラス)を作ろう! • 変数や関数は、クラスの外に見せるものと 見せないものを区別しよう • 異なるクラスでも、似たような動作をする関数には 同じ名前をつけよう • 似たようなクラスは、その違う部分のプログラムだけ を作ろう用語
• クラス–
型(構造体+関数) • フィールド、メンバ変数–
変数 • メソッド、メンバ関数–
関数 • メッセージを送る–
関数呼び出し • インスタンス–
生成された変数 • コンストラクタ–
インスタンス生成時の初期化関数継承
(inheritance)
• 親クラス(super
クラス、基底クラス)—
継承される • 子クラス(sub
クラス、派生クラス)—
親クラスの変数・関数を引き継ぐ 親クラス 子クラス 子クラス extends インスタンス インスタンス new extends new new インスタンスオブジェクト指向
—
まとめ
• ユーザーが「新しい型」の変数を宣言できる • 型に関連した関数が「操作」のように見える • 関数名の命名に言語が介入—
継承を用いれば、似たような関数は同じ名前になる モジュール化に貢献 差分プログラミングが可能 変数名・関数名の命名はプログラマーの永遠の課題である が、それに対する補助となっている=⇒
身につけばあたりまえの思考パターンJava
とは
•
Sun Microsystems
が開発–
コマンドライン版の開発環境(SDK)
を無料で配布現在
Java1.4
(Java1.2
以降をJava2
と呼ぶ)• オブジェクト指向言語
•
Solaris, MS-Windows, Linux, Macintosh,
携帯電話等の多くの環境で動く
• コンパイラは中間コードを生成
• 実行には
Java Virtual Machine (VM)
が必要• キーワード:使用済メモリの自動開放 (garbage collection)、 豊富なライブラリ、アップレット、例外処理、国際化
Hello World!
// HelloWorld.java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
• <ソースファイル>HelloWorld.java
• [コンパイル]javac HelloWorld.java
• <実行ファイル>HelloWorld.class
• [実行]java HelloWorld
C
言語との相違
—
ソースファイルの構成
• 1クラスにつき1ソースファイル(.java)
(とにかくクラスが必要) • クラス名=ファイル名 • ヘッダ・マクロがない • 関数プロトタイプ宣言を先にする必要がない • 複数ファイルのコンパイルもjavac
コマンド1回 (必要クラスが自動でコンパイルされる)•
public static void main()
のあるクラスをjava
コマンC
言語との相違
—
変数の型
• 整数型はすべて符号付き
•
boolean
型がある• 文字列は
char
*
ではなくてString
• 配列は
int a[] = new int[10];
または
int[] a = new int[10];
• ポインタ表記(
*
, &
)はない • 変数はブロックの先頭でなくても宣言できる • 同じ関数名でも引数の型が異なれば別関数 型 ビット数byte
8
short
16
int
32
long
64
C
言語との類似点
• コメント(
/* */
,
//
)• 行制御(
if, for, while, do .. while, switch .. case
)• 変数名に使える文字
• 演算子
クラス
• 構成要素 ・ フィールド(変数) ・ コンストラクタ(初期化関数) ・ メソッド(関数) • 別クラスからの使用例int i = 1211;
Date date = new Date(2002, 12, 11);
date.print();
• フィールドやメソッドのアクセス制御
コンストラクタ
• インスタンス化(new)
の時に呼ばれる関数 • インスタンスの初期化を行うのに便利—
複雑な処理は避ける • メソッドとは次の点で異なる ・ クラス名と同じ名前 ・return
をつけない ・ 継承されない配列
(1/2)
•new
演算子で要素数を決めて定義 • 添字は0
から始まる •(
変数名).length
で要素数が得られる • 要素数あふれは実行時エラー(ArrayIndexOutOfBoundsException)
int a[] = new int[10];
//
4つとも等価int[] b = new int[10];
int c[];
c = new int[10];
int[] d;
d = new int[10];
配列
(2/2)
• 初期化には{
要素,
要素,...}
を代入 • オブジェクトの配列には都合2回のnew
が必要int[] a = { 1, 2, 3 };
// OK
int[] b;
b = { 1, 2, 3 };
//
コンパイルエラーDate dates[]
= new Date[100];
// dates[5]
の中身はnull
dates[5] = new Date(2002, 12, 11);
多次元配列
int[][] a, b;
//
2次元配列a = new int[3][7];
//
長方形b = new int[3][];
//
長方形ではないb[0] = new int[8];
b[1] = new int[9];
System.out.println(a.length);
// 3
System.out.println(a[0].length); // 7
System.out.println(b.length);
// 3
System.out.println(b[0].length); // 8
プリミティブ型
↔
オブジェクト型
• プリミティブ型
– new
不要• オブジェクト型
– new
必要プリミティブ型 オブジェクト型 特徴
boolean
Boolean
論理型char
Char
文字型(Unicode)
byte
Byte
short
Short
符号あり整数型int
Integer
long
Long
float
Float
浮動小数点型double
Double
String
(文字列を扱う特殊なクラス)
• プラス演算で文字列を連結する
• 文字列比較は equals() を使う
• 文字列を含む式の中ではどんなクラスも自動的に文字列に
変換される(toString() メソッドを自動呼び出し)
String s = "this" + "is" + "a" + "pen";
System.out.println(s); // thisisapen
int i = 5;
String t = "i = ";
static
付きフィールド
• クラスフィールドと呼ぶ • インスタンス間で共有される(同じ値を持つ) •(
クラス名).(
クラスフィールド名)
(
インスタンス名).(
クラスフィールド名)
どちらでもアクセスできる • 典型的には定数の宣言に用いる(final static)
static
付きメソッド
• クラスメソッドと呼ぶ • インスタンス化せずとも呼び出せる •(
クラス名).(
クラスメソッド名)
(
インスタンス名).(
クラスメソッド名)
どちらでもアクセスできる • 典型的にはmain()
や状態不要の数学関数Math.sin(x)
に用いる • クラスメソッド内からは普通のフィールド/メソッド を呼び出せない継承
• 継承したい子クラス名では、クラス名の後ろに
“extends
親クラス名”
を付加して宣言class SubClass extends SuperClass {
...
}
• 親クラスは1つ(=多重継承できない) • 子クラスは親のフィールドとメソッドを受け継ぐ—
親のメソッドを上書きして定義しなおすこともできる • すべてのクラスはObject
クラスの子クラス (たとえ明示的にextends
しなくても)インターフェイス
• インターフェイスはメソッドの型のみを宣言
public interface Comparable {
public int compareTo(Object o);
}
• 多重継承したい時の逃げ道
—
あるメソッドの存在を保証する手段Object
SubClass1 SubClass2 SubClass3
Comparable Comparable
インターフェイスの実装
• インターフェイスを実装したいクラスでは、クラス名
の後ろに
“implements
インターフェイス名”
を付加 して宣言class OrderedClass implements Comparable {
...
public int compareTo(Object o) { ... }
}
• インターフェイスを
,
で区切って複数指定できる• 必要なメソッドの実体を記述する
命名規則(習慣)
• クラス名・インターフェイス名は先頭大文字+単語の 切れ目大文字ex.
ClassName
• メソッド名・フィールド名は先頭小文字+単語の切れ 目大文字ex.
methodName(), variableName
•
final static
変数(マクロ定数相当)は全部大文字+単語の切れ目アンダースコア(
_
)ex.
CONSTANT_VALUE
• メソッド名は動詞+目的語や