06. Javaでオブジェクト指向(1/x)

2018年度版資料

前半は、第5回の続き、今回の課題 問1 の SNAP! で buzzer オブジェクトの動作確認、を行う。

後半は、Javaを扱う。

Javaの開発環境

eclipse4.7 を使用する。

起動方法:

Dドライブの pleiades4.7 フォルダ(旧バージョンのフォルダもあるので要注意) ※pleiades は eclipse を日本語化するプラグインのプロジェクト

→ eclipse → eclipse.exe をダブルクリック

今回の一番のポイント、プロジェクトの保存先の設定

標準の保存先が ../workspace となっているが、↓のように変更する。

※ワークスペースの設定画面がでたら、

参照 ボタン → 学籍番号のフォルダを選択 → 新しいフォルダーの作成 ボタン

フォルダ名 Java2018 を入力

作成したフォルダを選択して OK ボタン

起動 ボタン

※パスの設定画面が現れたら、「選択された変更を適用」方で進める。

ワークスペースの確認: ウインドウのタイトル部分に プロジェクトの保存先フォルダのパスが表示されている

eclipse の基本操作:

文字列「Hello world」をeclipseのコンソールに表示するコードの作成と実行。

パッケージ・エクスプローラー を右クリック → 新規 → Javaプロジェクト

・プロジェクト名 java0

・設定完了

※この画像は、次のクラスの作成まで済ませた状態。プロジェクト Java0 の内部に HelloWorld.java クラスファイルが置かれている。

HelloWorldクラスの作成:

プロジェクト java0 を右クリック → 新規 → クラス

・クラス名 HelloWorld

※文字小文字に注意 単語は空白で区切らず繋ぐ

・メソッド・スタブの main を使用する(チェックボックス ON)

次のコードを、eclipse のコード入力支援の ショートカット※ や テンプレート を利用しながら入力する。

コードを実行できる行まで入力したら、段階的に実行して動作を確認する。

IDE (統合開発環境) を利用した開発:

eclipse のキーボードショートカットを活用して、コード補完によるプログラム作成に慣れましょう。

Eclipseショートカットキーまとめ http://d.hatena.ne.jp/wyukawa/20090628/1246183795

Eclipse(エクリプス)良く使うショートカットキー http://www.shikaku-pass.com/sjcp6/eclipse-shortcutkey.html

便利なショートカットキー

入力候補テンプレート表示 Ctrl + Space

単語補完 Alt + /

クイックフィックス Ctrl + 1 (問題点の解決方法を提供)

コメントON・OFF Ctrl + /

インデント修正 Ctrl + I

1行削除 Ctrl + D

ソースコードのフォーマット Ctrl + Shift + F

補完入力中にキャメルケースの大文字部分の入力で絞込み 例) SytemHogeFuga は SHF で候補絞り込み

new SomeClass();と入力後、「Shift + Alt + L」で左辺側を補完

syso + Ctrl + Space で System.out.println()

入力するコード:

コードの実行方法: 実行構成ウインドウの Javaアプリケーション を ダブルクリック する

プログラムの実行結果:

提出物:Webclassにアップロード

※トラブル対応用に作業済みファイルを HelloWorld.java として、このページに添付してある。

問題1 SNAP! でOOPで buzzer オブジェクトが動作している状況の画面のスクリーンショット。

問題2 HelloWorld.java ファイルをワークスペースから探してアップロード。

補足資料:

書籍など:

CODESPELL – JAVA言語がそのまま呪文となる教育用3Dゲーム(紹介記事HTTP://CODESPELLS.ORG/

連載企画 最強のJava入門書はどれか?(2016年秋)

Javaの文法学習について:

C言語を元に、プログラムの表記文法が出来ています。

Cに加えて、オブジェクト指向に対応した文法、 総称プログラミング(ジェネリクス)、拡張 for ループ、λ(ラムダ)式 などの文法拡張も有ります。

「java 最速マスター」 で検索すると、文法をコンパクトにまとめた記事がみつかるので、ざっと目を通しておくとよいでしょう。

例えば基礎文法(C言語的な)は、 こちら に。

オブジェクト指向の部分は、ドットインストールの後半の記事が参考になりそうです。

Javaのマイナーな、マニアックな文法が 変態文法 として記事になっています。

大学の WebClass の 全学共通コース に Java入門 のコースがあります。

Wikipedia にも Java文法のページあり

以下、2016年度版資料

・出席はWebClassに登録

メモ:

課題2 Kadai02

3枚の画像の中から、ランダムに1枚画像を選んで表示するプログラムの作成。

画像のファイル名を、 String[] の配列として登録して利用する。

先週の続き、↑の課題の解説から。

※ 先週の課題の作成例のソースコードがページの最下部に添付されているので参照して利用する。

先回の課題について:

旧資料の中で提示された課題は、練習用として各自に任せます。

05. Javaでオブジェクト指向(2/4) のページの下の方に記載の、画像を表示する演習について取り組んでください。

キーワード: クラス インスタンス コンストラクタ

旧科目 応用プログラミング1 の資料を参照

第5回と第6回の内容

※資料が、ところどころリンク切れしています。

http://kaz.cyteen.nagoya-bunri.a.jp/ の部分を http://www.nagoya-bunri.ac.jp/~kobashi/lec/ に置き換えると表示できます。

課題については、以下のものに取り組む。

プロジェクト名 Project3

課題1:

添付ファイル Maze2.java を利用して、第5回 ↓のプログラムを修正する。

例) 配列を利用した迷路(マップ)の表現 これに、スタート位置やゴールを表示する様なif 文 を組み込む、迷路のサイズを拡大する、など。

※例を Maze2a.javaとしてこのページに添付しておく。

課題2:

Javaの拡張 for の文法で、 Maze2 を書き直してみよう。

クラス名は Maze3など適当に指定し、新しいクラスとして定義すること。

(ヒント) paint() のコードを修正

2次元配列 maze の中には 1次元配列が並んで入っている。その1次元配列(複数のx方向のデータ)を xs として

とりだす。

取り出した xs から、x方向の各要素を a として取り出す。

for( int[] xs : maze )

for( int a : xs )

(応用)配列の要素を全スキャンするテクニックについて調べてみよう。

課題3:

第6回 L6b 回文の作成 String と StringBuffer オブジェクト

第6回 L6_1b 図形描画 Point オブジェクト

※L6_1b の修正点

L6_1b では、Webの資料通りに translate(200,200) でアプレットの初期画面サイズ(300x300)を超える場所に

Pointを移動させようとすると、paint()がシステムから呼び出され、想定外の場所まで Pointが移動してしまう。

そこで、 移動量を小さくし translate(20,20) アプレットの初期画面サイズを拡大して、対応する。

アプレットの初期サイズを変更する方法

例) ループで translate を繰り返し実行して図形を描画

※添付ファイルL6_1b2について

上記のコードでは、3点の座標p1 p2 p3 を結んで1個の三角形を描き、画面がクリアされる前にその3角形を移動させ、グラフィックメモリ上に重ね書きしている。

ウィンドウサイズをマウスで拡大すると、複数回のrepaintによる画面のクリアと再描画が実行されて、

3角形は何度も移動を繰り返し、すぐに画面外に移動してしまうので何もウィンドウに描画されなくなる。

そこで、画面に表示する3角形の個数分の Polygonオブジェクトを用意し、画面に複数の3角形を描くようにコードを修正した。

複数のPolygonオブジェクトを 配列 Point[] で記録するコードを L6_1b2

複数のPolygonオブジェクトを リスト ArrayList<Point> で記録するコードを L6_1b2a

として添付しておく。

応用:

・Javaで、n回ループ(回数指定)を実現する方法を調べる。

・イテレーターについて調べる。

C言語風の旧来のfor 文では ループ回数の制御変数を用意し、制御変数の更新条件と、ループの終了条件をプログラムで記述してループを制御していた。

ところが、拡張 for 文では制御変数を用いずに、配列など(※1)の集合的データ(コレクション)をループで処理することができる。

その際、コレクションに含まれる要素に順番にアクセスし、全ての要素を処理する。

つまり、拡張for のループの実行回数は通常は、要素の数と等しい。

では、100回のループのために、要素数100のコレクションを用意すれば、拡張for で100回ループできることになるが、プログラムの手間や効率は悪い。

もっと良い方法はないだろうか?

※1関連情報 イテレータと拡張 for文 配列以外に、List や Set や Map などコレクションクラス(集合的データ)を拡張 for で処理できます。

※関連情報 DCL02-J. 拡張 for 文のループ変数は必ず final 宣言する

※※ Java8では配列とコレクションに対して forEachメソッドが用意されている Java8のforEachを使った繰り返し処理について

(ヒント)

Stream API を利用する。 Java8 では、データを連続して処理するための Stream APIが強化された。

Stream API を利用して、 0 1 2 3 ... 99 のようなデータ列を生成し、 forEach メソッドで順に処理することができる。

例)

import java.util.stream.IntStream;

public class Test01 {

public static void main(String[] args) {

IntStream intst = IntStream.range(0,6); // 0 1 2 3 4 5 のInt値ストリームを生成する。

// e -> System.out.println(e) は ラムダ式。仮引数 e でストリームから値を受け取り処理する式。

intst.forEach(e -> System.out.println(e));

System.out.println("-----1");

intst = IntStream.rangeClosed(1, 6); // 1 2 3 4 5 6 のストリームを生成する。第2パラメータの値をストリームの範囲に含む。

intst.forEach(e -> System.out.println(e));

System.out.println("-----2");

intst = IntStream.range(0,3);

// toArray()のコスト高そう

for(int e:intst.toArray()){

System.out.println(e);

}

System.out.println("-----3");

IntStream.range(-3, 0).forEach(e -> System.out.println(e));

// Java8 の メソッド参照 を使った表記。printlnメソッドは引数が1つなのでラムダ式として扱える。

System.out.println("-----4");

IntStream.range(0, 3).forEach(System.out::println);

System.out.println("-----5");

// 従来の書き方と比較

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

System.out.println(i);

}

}

}

Java8のStream APIの使い方(Streamの生成編)

Stream API の遅延処理

関数型プログラミングって何、ラムダってなんだよ

----以下来週にまわします----

第7回 問題2

タートルグラフィックスシステムの制作:

基本:

コンソールアプリケーションで、メッセージ(文字列)でキャラクターの行動を表現する

例)

ネコとクラスとインスタンス・スタティック

↑のプログラムに コンストラクタ を追加して、name に初期値を与える。

↑のプログラムに ねこ の現在の座標を管理する インスタンス変数 x y を追加して、移動するたびに値を更新するようにする。

↑のプログラムに report() メソッドを追加し、現在の座標を報告(コンソールに出力)するようにする。

応用:

Java Applet 画面上に、タートルグラフィックスを描く ねこクラスを作成する。

グラフィックスの描画には、アニメーション処理 は付けなくてよい。

例えば、猫が、直進 100 右回転90 直進 100 右回転90 直進 100 右回転90 直進 100 右回転90 と動いた場合、画面には サイズ100の正方形が表示されるようにすること。

(ヒント)

ねこ クラス に命令された内容を記憶する commands クラス 配列を持たせる。

ねこ クラス に commands クラス配列 の内容に応じでグラフィックスを描画する、 execute() メソッドを作成する。