#author("2019-11-21T16:02:22+09:00","ocha","ocha")
//#contents


*マルチメディアプログラミング実習 2019年度後期 [#d33b7775]

**今後の予定 [#de7840d4]

-10月24日 椎尾学会出張のため休講
-11月7日 椎尾病欠のため休講(すみませんでした)
-1月16日 月曜授業日のため授業なし
-1月23日 最終授業日



**2019年11月21日: エラー、String、コレクション[#mf116c61]

***本日のレポート [#n970e36c]

EtoJ.javaとEtoJ.classを出席番号+名前のフォルダーにコピーして、圧縮して提出してください。


***Hash Map [#ac67b323]

https://docs.oracle.com/javase/jp/8/docs/api/index.html

2つのインスタンスのマッッピング(対応付け)の集まりを保持するクラスです。2つのインスタンスをキー(key)と値(value)と言います。例えば、keyもvalueもどちらもStringインスタンスの場合、以下のようにして要素を追加していきます。

 import java.util.*;
 
 public class EtoJ{
 
 public static void main(String args[]) {
 	HashMap<String,String> map = new HashMap<String,String>();
 	
 	map.put("apple","りんご");
 	map.put("banana","バナナ");
 ...
 
 }
 }

このプログラムで、mapインスタンスからkeyに対応するvalueを取り出すためには、

 map.get("apple");

などとします。


このプログラムを拡張して、以下のように動作する英語ー日本語単語変換プログラムを作ってください。

 [e100:?/Documents/java] siio% java EtoJ banana
 バナナ
 [e100:?/Documents/java] siio% java EtoJ apple
 りんご
 [e100:?/Documents/java] siio% java EtoJ 
 Please input an English word




------------


***Hash Set [#h59a37b5]

https://docs.oracle.com/javase/jp/8/docs/api/index.html

Linked Listと同様にインスタンスの集まりを保持するデータ構造です。

 (element 1) ---> (element 2) ---> (element 3) ---> ... (element n)

だだし、同一要素を重複して保持しません。

 import java.util.*;
 
 public class HashSetTest{
     public static void main(String args[]){
         HashSet<String> set = new HashSet<String>();
         String name1="Alice";
         String name2="Bob";
         String name3="Cindy";
 
 //setにname1をaddしてください
 //setにname2をaddしてください
 //setにname3をaddしてください
 //setに再びname1をaddしてみてください。その時の戻り値 (booleanです)の状態を表示してください。
  
 //setの内容をIteratorを使って全部表示してください。
 
     }
 }


解答例:

 import java.util.*;
  
  public class HashSetTest{
      public static void main(String args[]){
          HashSet<String> set = new HashSet<String>();
          String name1="Alice";
          String name2="Bob";
          String name3="Cindy";
  
 //name1,2,3を追加
 	set.add(name1);
 	set.add(name2);
 	set.add(name3);
 //name1の再度追加を試みる。失敗
 	System.out.println(set.add(name1));
   
 	Iterator it = set.iterator();
 	while(it.hasNext())
 		System.out.println(it.next());
  
      }
  }




***Linked List [#n28a2bc2]

https://docs.oracle.com/javase/jp/8/docs/api/index.html

要素があって、次の要素へのポインターを持っているような、リスト構造です。

 (element 1) ---> (element 2) ---> (element 3) ---> ...  ---> (element n)

次のプログラムを作ってLinked Listのメソッドを使ってみましょう。
定義とコンストラクタで<String>と書くのは、要素がStringのインスタンスだという宣言です。
昔のJavaでは不要だったのですが、今のバージョンではこのような形式で明示的に書かないといけないようです。

 import java.util.*;
 
 public class LinkedListTest{
         public static void main(String[] args) {
                 LinkedList<String> list = new LinkedList<String>();
                 String name1="ALICE";
                 String name2="BOB";
 
 //listにname1をaddしてください
 //listにname2をaddしてください
 //listの要素数を取得して表示してください
 //listから最初の要素をgetFirstで取り出して表示してください
 //listからget(1)してその結果を表示してください
 
                 String name3="CINDY";
                 String name4="DAVE";
  
 //listにname3をaddしてください。
 //listからname1を削除してください(remove)
 //listにname4をaddFirstしてください。
 //この結果、"DAVE" --> "BOB" --> "CINDY"となると思います。
 
 //listの全要素にアクセスするには、Iteratorインスタンスを作ると便利です。
 //以下のようにして全要素を表示してください。
 
         Iterator it = list.iterator();
     
         while(it.hasNext()) {
                 String st = (String)it.next();
                 System.out.println(st);
          }
 
 //toArrayメソッドで配列を作ることもできます
 //以下のようにして全要素を表示してください。
 
         Object[] names = list.toArray();
         for(Object s: names) System.out.println(s);
     }
 }

解答例:

 Import java.util.*;
 
 public class LinkedListTest{
 
 	public static void main(String args[]){
 
 	LinkedList<String> list = new LinkedList<String>();
 
 	String name1 = "ALICE";
 	String name2 = "BOB";
 
 	list.add(name1);
 	list.add(name2);
 	
 	
 	System.out.println(list.size());
 	System.out.println(list.getFirst());
 	System.out.println(list.get(1));
 
 	String name3 = "CINDY";
 	String name4 = "DAVE";
 
 	list.add(name3);
 	list.remove(name1);
 	list.addFirst(name4);
 
 	Iterator it = list.iterator();
 	while(it.hasNext()) System.out.println(it.next());
 
 	Object[] names = list.toArray();
 	for(Object s: names) System.out.println(s);
 
 	}
 
 }

解答例(丁寧版):

 import java.util.*;
 
 public class LinkedListTest{
         public static void main(String[] args) {
                 LinkedList<String> list = new LinkedList<String>();
                 String name1="ALICE";
                 String name2="BOB";
                 list.add(name1);
                 list.add(name2);
                 String firstname=list.getFirst();
                 String secondname=list.get(1);
                 System.out.println("listの要素数は" + list.size());
                 System.out.println("listの最初の要素は" + firstname + "2番目の要素は" + secondname);    
                
                 String name3="CINDY";
                 String name4="DAVE";
                 list.add(name3); 
                 list.remove(name1);
                 list.addFirst(name4);
                
                 Iterator it = list.iterator();
                 System.out.println("要素の走査");
                 while(it.hasNext()){
                         String st = (String)it.next();
                         System.out.println(st);
                 }
                 
 
                 System.out.println("要素の走査 by toArray()");
                 Object[] names = list.toArray();
                 for(Object s: names) System.out.println(s);
 
         }
 }


----------

**第10章 Stringクラスとコレクションフレームワーク [#w938c6ce]

以下のリンクからStringクラスを選択して、何ができるかざっと見ておきましょう。

https://docs.oracle.com/javase/jp/8/docs/api/index.html


***Stringのメソッドをいくつか使ってみましょう [#v7994c3d]

 public class TestString {
     public static void main (String argue[]) {
 
     String str = "Hello Java World";
 
     //このstrを表示してください(System out.printlnを使う)
 
     //strの長さを表示してください(.lengthを使う))
 
     //strの3要素目の文字を表示してください
 
     //最初にaが現れる位置を表示してください
 
     //最後の文字aが現れる位置を表示してください
 
     //辞書式で比較してstrと次のstr2のどちらが先に現れるかを表示してください(compareToを使う)
     String str2="Hello World";
 
     //strの6要素目から始まる部分文字列を作り表示して表示してください。
 
     //int型をString型に変換してください。
     int v2020=2020;
     String s2020 = String.valueOf(v2020);
 
     }
 }


解答例:

 public class TestString{
 	public static void main(String args[]){
 		String str = "Hello Java World";
 
 		System.out.println(str);
 		System.out.println(str.length());
 		System.out.println(str.charAt(3));
 		System.out.println(str.indexOf('a'));
 		
 		String str2 = "Hello World";
 
 		System.out.println(str.compareTo(str2));
 		System.out.println(str2.compareTo(str));
 
 		System.out.println(str.substring(6));
 
 		int v2020=2020;
 		String s2020 = String.valueOf(v2020);
 		System.out.println(s2020);
 	}
 }



***最初の引数(文字列)を表示するプログラムを作る。クラス名はTestString [#xb389032]

 public class TestString {
	public static void main(String argv[]) {
		System.out.println(argv[0]);
	}
 }

***演習1:最初の引数(文字列)を逆に出力するプログラムを作る [#k9b3a112]

 [e100:?/Documents/java] siio% java TestString ochanomizu
 ochanomizu
 uzimonahco
 [e100:?/Documents/java] siio% 
 
さらには、引数がない場合は引数入力を促すことを表示してみよう。
 
 [e100:?/Documents/java] siio% java TestString
 please input a word
 [e100:?/Documents/java] siio%

解答例:

 public class TestString {
 	public static void main (String argv[]) {
 		try{
 			System.out.println(argv[0]);
 			int len = argv[0].length();
 			for(int i = len - 1; i>=0; i--) {
 				System.out.print(argv[0].charAt(i));
 			}
 			System.out.println();
 		}
 		catch (Exception e) {
 			System.out.println("please input a word");
 		}
 	}
 }


----------

C言語では、エラーが出そうな処理をする場合は、エラーが発生するかどうかをステップごとにif文でチェックして、対処していました。プログラムが読みにくく煩雑になりがちです。

現代的な言語では、プログラムの処理をブロックでまとめて、その部分から発生したエラーを別の部分で受け取って処理をする書き方ができます。

Javaの多くのメソッドが標準的なエラー処理をサポートしています。また、自分でエラー処理を設計することも可能です。ただ、この授業の範囲では、自分でエラー処理を設計することはないと思います。標準的な機能の利用を練習しておきます。

次のプログラムを作って試してください。
引数が2個あることを前提としています。
なので、引数が少ないとエラーが出ます。確認してください。

 public class TestException {
 	public static void main(String argv[]){
 			System.out.println(argv[0]+" "+argv[1]);
 			System.out.println("Nice to meet you.");
 	}
 }



エラーが出る可能性のある場所をtryでくくっておき、
エラーが出たらそれを捕捉する処置をcatchで指定します。

 public class TestException {
 	public static void main(String argv[]){
 		try{	
 			System.out.println(argv[0]+" "+argv[1]);
 			System.out.println("Nice to meet you.");
 		}
 		catch (Exception e) {
 			System.out.println("please input 2 words.");
 		}
 	}
 }


-------------

**2019年11月14日:継承 [#ifca9b32]

***本日のレポート [#w6a5e3c7]

作成したOsaifuUSD.javaとOsaifuUSD.classをいつものように出席番号と名前のフォルダにコピーして、圧縮して提出してください。

***実行時の型 [#h051144d]

サブクラスもちゃんとしたクラスですので、インスタンスを作ったらそのクラス型の変数に代入します。
例えば、ParentというクラスからChildというサブクラスを作ったとします。通常は、

 Child x = new Child();

として使います。ここで親のクラスの変数に代入することもできます。

 Parent y = new Child();

しかし、親のインスタンスを、子の型の変数には代入できません。

 Child z = new Parent(); //これはできない

仕組みを考えれば理由は明白です。サブクラスは、スーパークラスの機能を全部持っているので、インスタンスを親の型にキャストしても問題ありません。逆に、親の型をサブクラスの型に変換すると、拡張された部分のメンバーを呼び出されたときに、対応できません。

instanceofという演算子があります。上記の例では、

 if ( x instanceof Child) {}
 if ( x instanceof Parent) {{}

とするとifの中の判定はどちらもtrueです。あるクラスのインスタンスは、そのクラスのインスタンスでもあり、そのスーパークラスのインスタンスでもあるのです。

***抽象クラス [#eece29ff]

抽象クラスは、インスタンスを作れないクラスです。
いくつかのクラスの上位概念をまとめる役割があります。
例えば、犬クラス、猫クラスというクラスがあって、それらの上位概念として動物クラスを作ったとします。
その世界では、犬や猫のインスタンスは作れても、動物のインスタンスは作れないという設定にするのが自然かもしれません。
としたら、動物クラスは抽象クラスになります。
定義のオプションにabstractと書きます。

     abstract class Animal {}

この授業で抽象クラスを作成することはないと思いますが、マニュアルを見て発見したクラスのインスタンスを作ろうとすると、「抽象クラスだからインスタンスは作れない」というエラーが出ることがあります。そのクラスのサブクラスを探して、それを使ってください。

Readerは抽象クラスです。下のリンクからReaderを探してみてください。

https://docs.oracle.com/javase/jp/8/docs/api/index.html


***抽象メソッド [#v050fd26]

抽象クラスと同様に、特定のメソッドがabstractと定義されることもあるようです。稀なケースだと思います。この場合も、サブクラスでオーバーライドして定義する必要があります。

     public abstract void xxxx();

***finalクラス [#tf82758d]

クラスの定義にfinalをつけることができます。これ以上継承して欲しくない場合につけます。

     final class XXXX {}

メソッドの定義につけることもできます。サブクラスでオーバーライドして欲しくない場合に使います。

     public final void XXXX(){}

***インタフェース [#k5d21dd0]

抽象クラスに似ていますがクラスではないので、インスタンス化もサブクラス作成もできません。
抽象メソッドと定数だけが定義されています。
この授業でインタフェースを定義することはないと思いますが、たくさん利用します。
インタフェースには空のメソッドが定義されています。
そのメソッドを実装していますという宣言にimplementsという予約語を使います。
例えば、MovableとErasableというインタフェースが定義されていて、
クラスの定義で、これらを実装しているという宣言は、以下のように書きます。

     class MyShape implements Movable, Erasable {}

このクラスでは、Movable, Erasableで定義されているメソッドを全て実装していないといけません。
ややこしいですが、後の授業で、実例がたくさん出てきますので、そこでまた理解してください。

Mouse Listenerはインタフェースの例です。下のリンクから探してみてください。

https://docs.oracle.com/javase/jp/8/docs/api/index.html


***小テスト練習 [#g4c60a6e]

次回またはその次くらいの授業で、小テストを行います。
以下の内容が理解できるように、整理しておいてください。

以下のプログラムの中で、
クラス、インスタンス、サブクラス、スーパクラス、クラスメソッド、インスタンスメソッドがどれであり、
インスタンス化、継承がどこで行われているのか確認してください。
(importで始まる一行目はまだ説明していない内容なので小テストでは扱いません。無視してください)


 import javax.swing.JFrame;
 
  public class SampleWindow extends JFrame {
 	public static void main(String args[]) {
 		SampleWindow w = new SampleWindow();
  		w.setVisible(true);
 	}
  }



-----------------

***オーバーライド [#ad8de445]

サブクラスに、スーパークラスと同じ名前と引数のメソッドを書くこともできます。
これをオーバライドト言います。
一つのクラスの中で、名前が同じメソッドを定義することをオーバーロードという言葉でお話ししました。
似ていますが、オーバーライドは、引数のパターンも同じです。
スーパークラスのメソッドを置き換えるものです。
ここでは、スーパークラスのprint()メソッドをサブクラスでオーバーライドしてみます。

***スーパークラスのメソッドの呼び出し [#d39dcf0b]

オーバーライドすると、通常(thisが使われる場合)はサブクラスで定義されたメソッドが実行されます。
つまりサブクラスの定義の中で、

 print();
 this.print();

はどちらもサブクラスのprint()が呼び出されます。
でも、明示的にスーパークラスで定義された方のメソッドを実行することも可能です。
その場合は、メソッドを呼び出すときにsuperと追記します。以下のようにします。

 super.print();


*** OsaifuUSDクラスの改造(2) [#sa44f577]

OsaifuUSDにprint()メソッドを追加して、
円表示の次の行に ( xxx USD ) と残高をUSD表示するようにしてください。
円表示を行う部分はスーパークラスOsaifuのインスタンスメソッドprint()を利用することを考えてみてください。


http://gyazo.com/39a7b24a8c45e15ac55693592c2eb7cf.png



-解答例

 	public void print() {
 		super.print();
 		System.out.println("( " + (okane / 90) + " usd )" );
 	}



-----------------

*** OsaifuUSDクラスの改造(1) [#g8c0b7a2]

入出金のメソッドの中で、親の入出金メソッドを活用してみましょう。

 public class OsaifuUSD extends Osaifu {
 
 	public int outUSD(int usd) {
 		return ( out( use * 90) / 90 );
 	}
 
 	public void inUSD(int usd) {
 		in( usd * 90 );
 	}
 	
 …
 
 }

このプログラムの中のoutメソッドとinメソッドは、親のクラスで定義されたメソッドです。
outメソッドで残金がマイナスにならないように処理してあれば、そのまま仕組みを利用することができます。

親のメソッドを呼ぶことを明示的に書くためにsuper.をつかってもよいです。

 public class OsaifuUSD extends Osaifu {
 
 	public int outUSD(int usd) {
 		return ( super.out( use * 90) / 90 );
 	}
 
 	public void inUSD(int usd) {
 		super.in( usd * 90 );
 	}
 	
 …
 
 }



------------


**第8章 継承 [#ka97b6ac]

*** Osaifuクラスを継承してOsaifuUSDクラスを作ってみよう [#fc83e4ee]
-OsaifuUSDクラスはアメリカで買い物をするときに便利な、アメリカドルでお金を出し入れできる財布です。
-あたらしく追加するメソッドは以下です
-- void inUSD(int x)   xドルをお財布に入金します。このとき円に換算して残高に追加します
-- int outUSD(int x)   xドルをお財布から出金します。このとき円に換算した金額だけ残高が減ります。戻り値はドルにしましょう。
--1ドルは90円にしてください(今とはかけ離れた値ですが、サンプルの画像がそれで作ってあるので、すみません)
//-スーパークラスのメソッドを上書きするメソッドは以下です
//-- void print()   お財布の残高を円とドルで表示します
-OsaifuUSDクラスをテストするmain()メソッドでは次のことをやってください
-- OsaifuUSDインスタンスを一つ作ってそれをsaifu1という名前にする
-- OsaifuUSDインスタンスをもう一つ作ってそれをsaifu2という名前にする
--saifu1に1000円入金する
--saifu2に5ドル入金する
--saifu1とsaifu2が持っている金額を印刷する
--saifu1から2ドル出金してそれをsaifu2に入金する
--saifu1とsaifu2が持っている金額を印刷する

-動作例

http://gyazo.com/f51ea5895aaab32bb30b9a940d91515d.png

-ヒント:一行目はこれ

 public class OsaifuUSD extends Osaifu {



-ヒント:mainはこんな感じ

 	public static void main(String argv[]) {
 		OsaifuUSD saifu1= new OsaifuUSD();
 		OsaifuUSD saifu2=new OsaifuUSD();
 		saifu1.in(1000);
 		saifu2.inUSD(5);
 		saifu1.print();
 		saifu2.print();
 		saifu2.inUSD(saifu1.outUSD(2));
 		saifu1.print();
 		saifu2.print();
 	}


-解答例

一番シンプルな解答例です。残高がマイナスになることは考慮していません。

 public class OsaifuUSD extends Osaifu {
 
 	public int outUSD(int usd) {
 		okane-=usd * 90;
 		return usd;
 	}
 
 	public void inUSD(int usd) {
 		okane+=usd * 90;
 	}
 	
 	public static void main(String argv[]) {
 		OsaifuUSD saifu1 = new OsaifuUSD();
 		OsaifuUSD saifu2 = new OsaifuUSD();
 		saifu1.in(1000);
 		saifu2.inUSD(5);
 		saifu1.print();
 		saifu2.print();
 		saifu2.inUSD(saifu1.outUSD(2));
 		saifu1.print();
 		saifu2.print();
 		
 	}
 }

大昔の授業で使ったプログラムを使い続けているので、為替レートが90円になっています。
多分現在の為替レートとはかけ離れています。
(スクリーンショットを撮りなおすのが面倒なので、古いレートのままになっています)
為替レートを変数として持たせるとしたら、どうしたら良いでしょうか?

- インスタンス変数
- クラス変数

のどちらにするか、考えてみましょう。

[解答]インスタンスで共通の情報ですので、おそらくクラス変数で定義するのが良いと思います。

------------------

オブジェクト指向言語では、クラスを拡張するいくつかの方法が導入されています。
Javaなどで一般的な手法は、継承です。引き継ぐということです。

すでにあるクラスの機能を拡張して、新しいクラスを作ることを考えます。
拡張する部分は新しく作るのですが、拡張しない部分は、古いクラスのまま使いたいところです。
通常は、古いクラスをコピーして、機能拡張して新しいクラスを作ることが考えられます。
でも、古いクラスの方も、そのまま使われ続けて、改良され続けるとしたら、新しいクラスにコピーした部分には反映されないことになります。

そこで継承を使います。

例えば、たい焼きの焼き型で説明します。
とても気に入った焼き型があるけど、しっぽに模様がないのだけが不満というケースを考えてみます。
そこで、現在の焼き型を親として、継承する新しい焼き型を作ります。
継承したクラスで定義すると、それだけが差分として使われます。
なので、しっぽの模様だけ定義しておけば、あとは全て親の機能が使われます。
子クラスの中身は、極端な場合、空っぽでも良いです。定義されないメンバーは全て親のメンバーが使われます。

ということで、
別のクラスを継承することで、
差分だけを書いて機能を拡張していくことができます。

http://gyazo.com/2c8ef14d8be63b9fc18c58d79f2f3879.png


-------------


***インスタンスの参照 [#mb6379b9]

 Point pt1 = new Point(10,20);
 Point pt2 = pt1;
 Point pt3 = new Point(10,20);

この時、

 if(pt1 == pt2)

という判断をするとこれはtrueになります。

しかし

 if(pt1 == pt3)

という判断をすると結果はfalsです。

参照先が同じなのか、その中のインスタンス変数が同じなのかの違いです。インスタンス変数が同じかどうかは、その変数の値を直接調べて比較する必要があります。例えば、

 if( ( pt1.x == pt3.x) && (pt1.y == pt3.y) )

のようにします。


***ガーベージコレクションとファイナライザ [#w0dec2d2]

C言語ではmallocでメモリー確保した後、これを使わなくなったところでfreeしてシステムに返す必要がありました。そうしないと、どんどんメモリーを使ってしまうことになる可能性があります。この現象をメモリーリーク(メモリー漏洩)と呼ぶこともあります。オブジェクト指向言語でインスタンスを作る場合もシステムからメモリーを確保しています。これをシステムに返却する作業が必要な言語と、不要な言語があります。返却不要な言語は、使われなくなったメモリー領域を時々チェックして、自動的に返却してくれます。このような作業を(使われなくなった)ゴミ(のような領域を)集めると呼びます。ガーエージコレクションです。Javaではガーベージコレクションを行なってくれますので、newで確保した領域を、プログラマが明示的に返却する必要はありません。

インスタンスが破棄されるときに、何か特別な処置をしてほしいことがあります。例えば、インスタンスの中で入力をオープンして、破棄されるときにはクローズしたいという場合です。その場合は、finalize()メソッドを用意しておきます。そうすると、ガーベージコレクション対象になったところで、finalize()メソッドを自動的に起動してくれます。このメソッドのことをファイナラーザーとも呼びます。

***クラス変数の初期化 [#g403bd1b]

先に述べたように、インスタンス変数は、コンストラクタで初期化ができます。では、クラス変数はどうやって初期化するのでしょうか。

一つは、定義する場所で初期化できます。

 public class TestStatic [
     static int x = 10;
     y = 20;

ここでxはクラス変数で、yはインスタンス変数です。どちらも定義するところで初期化しています。

複雑な初期化をしたい場合は、staticイニシャライザを使用します。
例えば、10個の要素からなる配列を用意して、それの内容を添字の自乗になるよう初期化するには以下のようにします。

 public class TestStatic {
     static int[] array;
     static {
         array = new int[10];
         for (int I = 0; I < array.length; I++) array[I] = I * I;
     }

***final変数 [#c013ec29]

変数の宣言にfinalをつけると、その変数の値が変更の対象にならなくなります。クラス変数にfinalをつければ、定数を宣言する用途に使えます。C言語で#define文で定数を定義するような使い方ができます。

 final static double PI = 3.14159265;



-------------------


*** コンストラクタ [#y0f882f5]

コンストラクタはインスタンスが生成される時に自動的に呼び出されるメソッドです。コンストラクタを利用してインスタンスを初期化することができます。コンストラクタは「クラス名と同じ名前で、戻り値のないメソッド」です。先のPointクラスにコンストラクタを追加してみました。

 public class Point{
     int x, y;
 
     Point() { x = y = 0; }
 
     Point(int pix, int pty) {
         x = ptx; y= pty;
     }
 
 省略 
 
 }

インスタンスを生成する際の演算子newのあとに指定するのは、実はコンストラクタだったのです。コンストラクタは、演算子newとの組み合わせでのみ使用されます。上記で指定したコンストラクタは、次のように使われます。

 Point pt1 = new Point();
 Point pt2 = new Point(10, 20);

これで、最初のコンストラクタと、2番目のコンストラクタが呼び出されます。コンストラクタはnewを使用する時にしか使えません。

コンストラクタから他のメソッドを呼び出すことも可能です。例えばx,yを設定するメソッドがすでにあれば以下のように指定できます。

 Point(int pix, int pty) {
     set(ptx, pty);
 }
 
 void set(int ptx, int pty) {
     this.x = ptx; this.y = pty;
 }

コンストラクタの中でコンストラクタを呼び出すこともできます。

 Point() {
     this(0, 0);
 }

これはコンストラクタPoint (x, y)を呼び出しています。thisの使い方が今までと違って特殊です。


*** Osaifuクラスにコンストラクタを追加してみよう [#a8a56d7e]

-Osaifu() で残金0のインスタンスを作る
-Osaifu(int x) で引数を残金の初期値としたインスタンスを作る

ことができるコンストラクタを作りましょう。

これをmainから呼んで、上記のプログラムと同じことをするためには、

 		Osaifu saifu1 = new Osaifu(1000);//インスタンスを作る
 		//最初の保持金額を1000円にする
 		Osaifu saifu2 = new Osaifu(500);//インスタンスを作る
 		//最初の保持金額を500円にする

とすれば良いです。


***今日の提出課題 [#y418f281]

Osaifu.javaとclassを前回と同様にフォルダにコピーして、圧縮して提出してください。


***コンストラクタ解答編 [#w62499a7]

以下のコンストラクタを作ることになります。

 	Osaifu() { okane = 0; }
 	Osaifu(int x) { okane = x; }

これは以下のように書いても良いです。

 	Osaifu() { this(0); }
 	Osaifu(int x) { okane = x; }


-------------------

--解答例

	
 	double distance ( int ptx, int pty, int ptz ) {
 		int dx = ptx - this.x;
 		int dy = pty - this.y;
 		int dz = ptz - this.z;
 		return  Math.sqrt(dx * dx + dy * dy + dz * dz);
 	}
 	
 	double distance ( Point3D p ) {
 		return this.distance(p.getx(), p.gety(), p.getz());
 	}




**第7章 クラスとオブジェクトの操作 [#k1b96e7b]


***	他の点との距離を返すメソッドの例を説明しました [#xfa5f246]

 	double distance ( int ptx, int pty ) {
 		int dx = ptx - this.x;
 		int dy = pty - this.y;
 		return  Math.sqrt(dx * dx + dy * dy);
 	}
 	
 	double distance ( Point p ) {
 		return this.distance(p.getx(), p.gety());
 	}

distanceという名前は同じでも、引数の違いで、異なる動作をさせることができます。



*** Osaifuクラスを作ってみよう [#i9df5c2e]
-Osaifuクラスからはインスタンスがたくさん作られる
--Osaifuクラスはお財布の設計図/工場、ここから実際のお財布(インスタンス)が複数作られる
--工場出荷時の残金は0円だけど、その後、いろいろな値になるだろう(お金持ちのお財布には残金が多いだろうし、逆ならば少ないだろう)
--ということで残金はインスタンス変数とすべきだろう
-Osaifuクラスには次のメソッド、変数が必要だろう
--残金を表すインスタンス変数 int okane
--お金を入金するインスタンスメソッド void in(int x);
--お金を出金するインスタンスメソッド int out(int x);  戻り値は実際に出金できた金額(残金が不足ならばあるだけしか出せない)
--残金を印刷するインスタンスメソッドがあってもよいだろう void print(); &br;
http://gyazo.com/bd6eaafd220dc7ff791288089f293b28.png
-Osaifuクラスをテストするmain()メソッドでは次のことをやってください
-- Osaifuインスタンスを一つ作ってそれをsaifu1という名前にする
-- Osaifuインスタンスをもう一つ作ってそれをsaifu2という名前にする
--saifu1に1000円入金する
--saifu2に500円入金する
--saifu1とsaifu2が持っている金額を印刷する
--saifu1から200円出金してそれをsaifu2に入金する
--saifu1とsaifu2が持っている金額を印刷する

 	public static void main(String argv[]) {
 		Osaifu saifu1 = new Osaifu();
 		Osaifu saifu2 = new Osaifu();
 		saifu1.in(1000);
 		saifu2.in(500);
 		saifu1.print();
 		saifu2.print();
 		saifu2.in(saifu1.out(200));
 		saifu1.print();
 		saifu2.print();
 	}
 
http://gyazo.com/c618901458edc1ba338cab87d2810157.png

-Osaifu.java 解答編

 public class Osaifu {
 	int okane;	
 	public void in (int x) { okane += x; }
 	public int out(int x) { okane -= x; return x; }
 	public void print() {
 		System.out.println( "okane = " + okane +" yen");
 	}
 	
 	public static void main(String argv[]) {
 		Osaifu saifu1 = new Osaifu();
 		Osaifu saifu2 = new Osaifu();
 		saifu1.in(1000);
 		saifu2.in(500);
 		saifu1.print();
 		saifu2.print();
 		saifu2.in(saifu1.out(200));
 		saifu1.print();
 		saifu2.print();
 	}
 }

--このプログラムでは残金がマイナスになってしまってもかまわない設計になってしまっています。実際には残金だけの金額しか出せないはずなので、outメソッドを改良して、残金以上の金額を要求されたら、残金分だけしか出さないように変更してみてください。

--このためには、例えばoutメソッドを以下のようにすれば良い

 	public int out(int x) {
 		if(x < okane ) {
 			okane = okane -x;
 			return x;
 		} else {
 			int nokori = okane;
 			okane =0;
 			return nokori;
 		}
 	}	


-------------------

***変数には直接アクセスしないのが賢い設計 [#udb9cbfb]

C言語の構造体のように変数にアクセスできます。
でも、オブジェクト指向の設計では、外部からは極力変数にアクセスさせない設計が良いと言われています。
変数にアクセスするには、アクセス用のメソッドを使うのが良いと言うことです。
これにより、
変数の型などを将来変更してもメソッドの書き換えで対応できるからです。
修飾子をprivateにすると、クラスの外からアクセスできなくなって、保護できます。
そして、アクセス用のメソッドを書いておきます。

例えば、Pointクラスでしたら以下のようにします。

 public class Point {
 	private int x, y;
 	void set(int newx, int newy) {this.x=newx; this.y=newy;}
 	int getx() { return this.x;}
 	int gety() { return this.y;}
 
 	void print () {
 		System.out.println(this.x + ", " + this.y);
 	}
 
 	public static void main(String argv[]) {
 		Point pt1= new Point();
 		Point pt2 = new Point();
 		pt1.set(10,20);
 		pt2.set(-pt1.getx(), -pt1.gety());
 		pt1.print();
 		pt2.print();
 	}
 
 }


-演習5

Point3Dのメソッドを充実させて次のmain()メソッドで 

 10, 20, 30
 -10, -20, -30

という結果が出るようにしましょう


        public static void main(String argv[]) {
                Point3D pt1 = new Point3D();
                Point3D pt2 = new Point3D();
                pt1.set(10, 20, 30);//インスタンス変数を設定
                pt2.set(-pt1.getx(), -pt1.gety(), -pt1.getz());
                pt1.print();//インスタンスメソッド呼出
                pt2.print();
 
        }


***指定された座標との距離を返すメソッドdistance() [#sab2f953]

print()メソッドの他に、もう少し複雑な計算をするメソッドを考えてみましょう。特定の座標を指定した場合に、その座標との距離をdouble型で返すメソッドです。平方根を計算するMathクラスのクラスメソッドを使っています。

 	double distance ( int ptx, int pty ) {
 		int dx = ptx - this.x;
 		int dy = pty - this.y;
 		return  Math.sqrt(dx * dx + dy * dy );
 	}

今度は、座標ではなくて、他のPointインスタンスを引数にして、自分の点から、引数で与えられた点までの距離を返すメソッドと考えてみます。こんなメソッドです。

 	double distance ( Point p ) {
 		int dx = p.getx() - this.x;
 		int dy = p.gety() - this.y;
 		return  Math.sqrt(dx * dx + dy * dy );
 	}

この2つのメソッドは、どちらもPointクラスに実装することができます。よく見ると、先のメソッドと名前が同じです。C言語では名前が同じ関数を定義できませんでした。オブジェクト指向の言語では、引数の種類・数が違えば、同じ名前の関数を定義できます。引数を含めて関数を識別してくれます。このことを、多重定義、もしくはオーバーロードと呼びます。

違う関数ですので、片方のdistanceの中から、もう一方のdistanceを呼び出すこともできます。なので、以下のように定義することもできます。

 	double distance ( int ptx, int pty ) {
 		int dx = ptx - this.x;
 		int dy = pty - this.y;
 		return  Math.sqrt(dx * dx + dy * dy );
 	}
 
 	double distance ( Point p ) {
 		return this.distance(p.getx(), p.gety());
 	}


-演習6

Point3Dに、

- 他の座標との距離を返すメソッド double distance ( int ptx, int pty, int ptz ) と、
- 他のPoint3Dインスタンスとの距離を返すメソッド double distance ( Point3D p ) を実装して、

次のmain()メソッドで 


 10, 20, 30
 -10, -20, -30
 74.83314773547883

という結果が出るようにしましょう


        public static void main(String argv[]) {
                Point3D pt1 = new Point3D();
                Point3D pt2 = new Point3D();
                pt1.set(10, 20, 30);//インスタンス変数を設定
                pt2.set(-pt1.getx(), -pt1.gety(), -pt1.getz());
                pt1.print();//インスタンスメソッド呼出
                pt2.print();
 
                System.out.println(pt1.distance(pt2));
 
        }


----------------

***自分自身のメンバーへのアクセスthis [#ra357870]

クラス変数、クラスメソッド、インスタンス変数、インスタンスメソッドのことをメンバーと呼ぶこともあります。クラスやインスタンスを構成するメンバーという意味です。上記で説明したように、メンバーを指定するには、そのメンバーが属しているクラスまたはインスタンス(これらをまとめてオブジェクトとも呼びます)を書いて、そのあとにピリオドを書いて、メンバーを指定します。もう一度復習すると、クラスならば、

 Math.PI

でクラスMathのクラス変数のPIにアクセスできます(円周率が返ってきます)。

インスタンスならば、クラスからインスタンスを生成した後で、ピリオドでアクセスします。

 Point pt1 = new Point();
 pt1.print();

このようにメンバーにアクセスするには、そのメンバーが属しているオブジェクトを指定するのが正式なやり方です。ただし、同じオブジェクトの中のメンバーを指定する場合には、オブジェクトを略しても良いです。例えば、先のPointの例で、

 public class Point {
     int x, y;
 
     void print() {
         System.out.println(x + ", " + y);
     }
 
 }

と、書いてあります。インスタンスメソッドのprint()の中で、xとyを指定しています。これは自分自身のインスタンス変数です。なのでピリオドで指定していません。省略できるからです。

これをインスタンスの名前を指定して書くことはできるでしょうか?よく考えるととても難しいです。まずは、これは設計図段階での記述なので、これから作られたインスタンスにどのような名前がつけられるかわかりません。また、特定の名前を想定すると、別の名前をつけられた時に参照できないかもしれません。このような場合でも、自分自身のメンバーを指定しているのだということを明示的に書く方法があります。それがthisです。上の例は、

 public class Point {
     int x, y;
 
     void print() {
         System.out.println(this.x + ", " + this.y);
     }
 
 }

と書くこともできます。メソッドの中で一時的に宣言した変数ではなくて、メンバーにアクセスしているのだということがわかりやすいので、プログラムも読みやすくなります。thisは、積極的に使いましょう。




***public static void main の説明 [#ba29c5fb]

修飾子の説明:

- staticとついているのがクラス変数、クラスメソッドです
- staticが付いていないのがインスタンス変数、インスタンスメソッドです
- publicはすべてのクラスからアクセス可能
- protectedはサブクラスからアクセス可能(後で説明します)
- privateはそのクラスの中からのみアクセス可能

などから、今までお馴染みの、

 public static void main (String args[]) {}

は、どいういう意味だったでしょうか?考えてみてください。

- これはクラスメソッドです(staticなので。これが一番重要なこと)
- これは値を返しません(void)
- これはどのクラスからでもアクセスできます(publicなので。)

さらに説明すると、クラスメソッドmainは特別なメソッドで、javaコマンドが実行するメソッドです。なので、public static void main()があれば、javaコマンドはこれを実行します。つまり、

-javaコマンドは、引数のクラスのクラスメソッドmainを実行します
--staticと付いているのがクラス変数、クラスメソッドの印です
-今作ったPointクラスにもクラスメソッドmainを実装すれば自分自身をテストできます


***クラスの中に自分自身のインスタンスをテストするクラスメソッドmain()を作る [#v24b8d7a]

 public class Point {
        int x, y;
 
 	void print () {
 		System.out.println(this.x + ", " + this.y);
 	}
 
      public static void main(String args[]) {
                Point pt1 = new Point(); //自分自身からインスタンスを作る
                Point pt2 = new Point(); //自分自身からもう一つインスタンスを作る
 
                pt1.x = 10;
                pt1.y = 20;
 
                pt2.x = - pt1.x;
                pt2.y = - pt1.y;
 
                pt1.print();
                pt2.print();
     }
 
 }

これで、java Pointコマンドで、テストすることができます。
やっていることは、少しややこしいので、しっかり確認してください。
クラスメソッドの中で、自分が定義した方法で、インスタンスを作っています。そしてそれを操作しています。


-演習4

クラスPoint3Dに自分自身をテストするクラスメソッドmainを作ってみよう

http://gyazo.com/bdef2ab8e69f7f6e62273c2d67d7af2e.png

      public static void main(String args[]) {
                Point3D pt1 = new Point3D(); //自分自身からインスタンスを作る
                Point3D pt2 = new Point3D(); //自分自身からもう一つインスタンスを作る
 
                pt1.x = 10;
                pt1.y = 20;
                pt1.z = 30;
 
                pt2.x = - pt1.x;
                pt2.y = - pt1.y;
                pt2.z = - pt1.z;
 
                pt1.print();
                pt2.print();
     }


--------------

***クラス変数・メソッドとインスタンス変数・メソッド [#h86c1fa6]

変数とメソッドの定義に使われる修飾子や戻り値の表現は、C言語に似ています。

- 戻り値がなければvoidと書きます
- 戻り値があればその型を書きます。

以下はとても重要です。

- staticとついているのがクラス変数、クラスメソッドです。クラス名にピリオドをつけて呼び出します。
- staticが付いていないのがインスタンス変数、インスタンスメソッドです。インスタンス名にピリオドをつけて呼び出します。
(インスタンスを作らないと呼び出せません)

クラス変数にはクラス名を指定してピリオドでアクセスします。例えばjava言語には、Mathというクラスが用意されています。MathクラスにはPIというクラス変数が用意されています。なので、Math.PIでアクセスできます。

 class MathTest {  
 public static void main (String args[]) {
         System.out.println(Math.PI);
         }
 }

またMath.random()クラスメソッドで乱数が得られます。以前の演習で使いました。

インスタンス変数はインスタンスを作ってからアクセスします。上の例でPointクラスでprint()インスタンスメソッドを作りました。これは、

 Point pt1 = new Point();
 pt1.print();

としてアクセスできます。クラスメソッドではありませんので、Point.print()ではアクセスできません。インスタンスメソッドだからです。

そのほかの修飾子は、あとで説明しますが、アクセス制御だけ述べておきます。

- publicはすべてのクラスからアクセス可能
- protectedはサブクラスからアクセス可能(後で説明します)
- privateはそのクラスの中からのみアクセス可能

です。






--------------------------
まずは前回の復習をします。

-クラスは型、インスタンスはそれから作られたもの
--クラスがたいやきの焼き型だとすると、インスタンスはそれから作られたたいやき
--クラスは設計図でインスタンスはそれから作られたもの
-クラスとインスタンスそれぞれにメソッドと変数がある
--クラス変数 例:何個のインスタンスを作ったか?
--クラスメソッド 例:インスタンスを作れ
--インスタンス変数 例:ひとつのたいやきの重さ
--インスタンスメソッド 例:たいやきをxxグラム食べる

http://gyazo.com/bbdd3587977a172f7fa7f00c4f5787e0.png

***すごく簡単なクラスの例 [#kbcf21cf]

整数型のインスタンス変数を2個だけ持つクラスです。C言語の構造体に似ています。

 public class Point {
     int x, y;
 }


先のPoint型のクラスにインスタンスメソッドを1個追加しました。座標を表示するメソッドです。

 public class Point {
     int x, y;
 
     void print() {
         System.out.println(x + ", " + y);
     }
 
 }

***インスタンスの生成 [#cc06a50c]

クラスからインスタンスを作ることをインスタンス化またはインスタンシエーションと言います。

先のPointクラスとは別の、テスト用クラスTestPointを用意して、その中でPointインスタンスを作るには、以下のようにします。
Pointクラスは別のファイルで定義されていることになりますが、同じディレクトリにそのファイルがあれば、ファイル名を手掛かりに探してくれます。

 public class TestPoint {
     public static void main(String args[]) {
         Point pt1 = new Point();
         Point pt2 = new Point();
     }
 }

配列の時と同じくnewコマンドが使われています。new Point()により、Pointクラスの設計図にしたがって、Point型インスタンスを格納するためのメモリー空間が確保されます。確保されたメモリー領域への参照をPoint型変数に代入しています。ここでは2つのインスタンスを作りました。同じ設計図(クラス)から作られましたが、それぞれ別のものです。

インスタンスのインスタンス変数、インスタンスメソッド(これらを合わせてメンバーと言うこともあります)にアクセスするためには、ピリオドを用います。C言語の構造体と同じです。

pt1とpt2のインスタンス変数に値を代入して、インスタンスメソッドprint()を呼び出すプログラムは以下のようになります。


 public class TestPoint {
     public static void main(String args[]) {
         Point pt1 = new Point();
         Point pt2 = new Point();
 
         pt1.x = 10;
         pt1.y = 20;
 
         pt2.x = - pt1.x;
         pt2.y = - pt1.y;
 
         pt1.print();
         pt2.print();
     }
 }

この結果、10, 20と-10, -20が表示されます。

- この後、以下の演習をやってもらいました。

TestPoint3Dというクラスを作って、その中のmain関数で、
先に作ったPoint3Dクラスからインスタンスを2個作り、それぞれの座標を10,20,30と-10,-20,-30に設定し、それぞれの内容をprint()メソッドを呼び出して表示するプログラムを作ってください。
以下のような実行結果が出るようにしてください

http://gyazo.com/deeb78a70a724a01ce76945235d42ab8.png















--------------------

**以下は、前回以前の授業の内容です。 [#iafdd8f4]

**2019年10月17日 [#d30d7432]



***インスタンスの生成 [#cc06a50c]

クラスからインスタンスを作ることをインスタンス化またはインスタンシエーションと言います。

先のPointクラスとは別の、テスト用クラスTestPointを用意して、その中でPointインスタンスを作るには、以下のようにします。
Pointクラスは別のファイルで定義されていることになりますが、同じディレクトリにそのファイルがあれば、ファイル名を手掛かりに探してくれます。

 public class TestPoint {
     public static void main(String args[]) {
         Point pt1 = new Point();
         Point pt2 = new Point();
     }
 }

配列の時と同じくnewコマンドが使われています。new Point()により、Pointクラスの設計図にしたがって、Point型インスタンスを格納するためのメモリー空間が確保されます。確保されたメモリー領域への参照をPoint型変数に代入しています。ここでは2つのインスタンスを作りました。同じ設計図(クラス)から作られましたが、それぞれ別のものです。

インスタンスのインスタンス変数、インスタンスメソッド(これらを合わせてメンバーと言うこともあります)にアクセスするためには、ピリオドを用います。C言語の構造体と同じです。

pt1とpt2のインスタンス変数に値を代入して、インスタンスメソッドprint()を呼び出すプログラムは以下のようになります。


 public class TestPoint {
     public static void main(String args[]) {
         Point pt1 = new Point();
         Point pt2 = new Point();
 
         pt1.x = 10;
         pt1.y = 20;
 
         pt2.x = - pt1.x;
         pt2.y = - pt1.y;
 
         pt1.print();
         pt2.print();
     }
 }

この結果、10, 20と-10, -20が表示されます。

- 演習3

TestPoint3Dというクラスを作って、その中のmain関数で、
先に作ったPoint3Dクラスからインスタンスを2個作り、それぞれの座標を10,20,30と-10,-20,-30に設定し、それぞれの内容をprint()メソッドを呼び出して表示するプログラムを作ってください。
以下のような実行結果が出るようにしてください

http://gyazo.com/deeb78a70a724a01ce76945235d42ab8.png

-----------

**第6章「クラスの基礎」 [#ncf7b7be]

***すごく簡単なクラスの例 [#vbf621fd]

整数型のインスタンス変数を2個だけ持つクラスです。C言語の構造体に似ています。

 public class Point {
     int x, y;
 }

- 演習1
3次元の座標x,y,zを表現するクラスPoint3Dを定義してください。ファイル名はPoint3D.javaです。
x,y,zはそれぞれint型とします。定義したらコンパイルしてください。

先のPoint型のクラスにインスタンスメソッドを1個追加します。座標を表示するメソッドです。


 public class Point {
     int x, y;
 
     void print() {
         System.out.println(x + ", " + y);
     }
 
 }


- 演習2
先のクラスPoint3Dのインスタンスの持つ座標x,y,zが10,20,30だった場合、その座標を10, 20, 30のように表示するインスタンスメソッドprint()を定義してください。定義したらコンパイルしてください。


--------

***クラスとインスタンスの説明をします。よく聞いてください。 [#tcd34c08]

まとめです:

-クラスは型、インスタンスはそれから作られたもの
--クラスがたいやきの焼き型だとすると、インスタンスはそれから作られたたいやき
--クラスは設計図でインスタンスはそれから作られたもの
-クラスとインスタンスそれぞれにメソッドと変数がある
--クラス変数 例:何個のインスタンスを作ったか?
--クラスメソッド 例:インスタンスを作れ
--インスタンス変数 例:ひとつのたいやきの重さ
--インスタンスメソッド 例:たいやきをxxグラム食べる


http://gyazo.com/bbdd3587977a172f7fa7f00c4f5787e0.png


-------------

-演習4

mainの引数argsは、Stringの配列で、コマンドラインで起動したとき、
コマンドの後に続けた書いた文字が入っています。
args[0], args[1], args[2] .... をすべてfor-each文で
表示するプログラムを書いてみましょう。
この時、以下のように、args[]の文字をすべてfor-each文で+つけて表示してみましょう。

 javac ArgsTest2 cat dog cow fox
 cat + dog + cow + fox

 public class ArgsTest2 {
 	public static void main(String args[]) {
 		boolean isFirstWord = true;
 		for(String s: args) {
 			if(false == isFirstWord) {
 				System.out.print(" + ");
 			}
 			isFirstWord = false;
 			System.out.print(s);
 		}
 		System.out.println();
 	}
 }



***for-each文 [#cd4a2794]

for-each文は、Cにはなかったです。練習しましょう。

 for(型 変数名: 式) {}

int型の4個の配列は、以下のように宣言できます。

 int[] array;
 array = new int[4]

これを1行で表現して、さらに初期値をいれてしまうこともできます。

 int[] array = new int[]{1,2,3,4};

- 演習3

 int[] array = new int[]{1,2,3,4};

で宣言した配列の中身を、for-each文で順番に表示せよ。ヒントは、

 for(int x: array) {}

です。

解答例:

 class ArrayTest {  
 public static void main (String args[]) {
 	int[] array = new int[]{1,2,3,4};
 	for (int x: array) {
 	     System.out.println(x);
 	     }
        }
 }






--------------

***for文 [#ac566ee5]

for文もC言語と同じです。

 for(初期設定; 条件; 再設定) {}

-演習2-1

10万円を今の1年もの定期預金の年利で複利で運用した時、元利合計が20万円を超えるのは何年後でしょうか?
for文で、2項目目に20万円を超える条件を書いて、年数と金額を表示するプログラムを作って調べてみましょう。

http://gyazo.com/1733defca0c709c41c69ea729320ab61.png

 for( year = 1; <ここに条件>; year++) { 

解答例:

 class Kinri {
 public static void main (String args[]) {
 	double okane=100000;
 	int year;
 	for(year=1; okane < 200000; year++) {
 		okane = okane * 1.002;
 		System.out.println("year = " + year + "  okane= " + okane);
 	 	year++;
 	}
 }
 }


-演習2-2

break文で直近のループを抜け出せます。上の問題を無限ループにして、break文で書き直してみましょう。


***while文 [#odd3e1de]

while文もC言語と同じです。

 while(条件) {}

-演習2-3

上の問題をwhile文で書き直してみましょう。

--------------


-演習1

100点満点のテストの得点から、ABCDの成績を表示するプログラムを作ります。
その準備のために、
0から100までの乱数を10個表示するプログラムを作ります。

 public class Score {
 	public static void main (String argv[]) {
 		int i,a;
 		for(i=0;i<10;i++) {
 			a=(int)(Math.random() * 100);
 			System.out.println(a);
 		}
 	}
 }


Math.random()は、Mathクラスのクラスメソッドであるrandom()を呼び出しているという意味です。
System.out.println()などと同じく、大文字で始まる単語はクラスを表します。


次にこの乱数を100点満点の点数とみなして、成績ABCDを表示するプログラムを書きましょう。
成績の基準は、80点以上がA, 60点以上80点未満がB, 40点以上60点未満がC, 40点未満がDです。
動作例を以下に示します。

http://gyazo.com/829b04a7fc82cdfe9dd0dfa650af873e.png

解答例1:

 public class Score {
 	public static void main(String args[]) {
 
 		int i,a;
 		char score;
 		for(i=0;i<10;i++){
 			a= (int)(Math.random() * 100);
 			if(a>=80) score='A';
 			else if(a>=60) score='B';
 			else if(a>=40) score='C';
 			else score='D';
 			System.out.println(a + " " + score);
 		}
 	}
 
 }

解答例2:

 public class Score {
 	public static void main (String argv[]) {
 		int i,a;
 		for(i=0;i<10;i++) {
 			a=(int)(Math.random() * 100);
 			System.out.print(a + " ");
 			if(a<40) System.out.println("D");
 			else if(a<60) System.out.println("C");
 			else if(a<80) System.out.println("B");
 			else System.out.println("A");
 		}
 	}
 }


-----------

**第5章「制御構造」 [#p54c6568]

制御構造も大半はC言語と同じです。

***if文、else文、else-if文 [#s3bd1b3d]

if文もC言語と同じです。

- if文

 if (a==0) b=100;

 if (a==0) {
    b=100;
 }

- if-else文

 if (a==0) {
    b=100;
 }else{
    b=10;
 }

- else-if文

 if (a>100) {
 }else if (a>10){
 }else{
 }

--------------

***第4章「演算子」 [#p4a8e735]

//--演習4.2をやってみよう

演算子はほとんどC言語と同じです。復習しましょう。

変数には算術演算子が使えます。算術演算子はC言語と同じです。

 +-*/%

です。%は剰余です。

 5 % 2

は1です。

代入演算子は=です。

算術演算子と代入演算子を組み合わせることもできます。

 a += 1;

は

 a = a + 1;

と同じ意味です。

インクレメント、デクレメント演算子もCと同様です。

 a = 1;
 b = a++;

は、bが1、aが2になります。

 a = 1;
 b = ++a;

は、a, bどちらも2になります。

関係演算子もC言語と同じです。

 <, >, <=, >=, ==, !=

論理演算子もC言語と同じです。

 &&, ||, !

Javaではbooleanにしか論理演算できないので、&, | だけでもokです。

ビット演算し、シフト演算子もC言語と同じです。

 &, |, ^, ~, <<, >>, >>>

 1 << 2

は4になります。

キャストもあります。C言語と同じです。

 long b=1234;
 int a = (int)b;







***文字列 [#t32f75c4]

C言語では文字列はただのバイト変数の配列でした。最後の値が0であることで、長さを知ることができる程度です(番兵方式)。
Javaでは文字列は、Stringクラスのインスタンスです。
なんのことかは後の授業で説明しますが、処理をする関数を内包している「構造体Structure」のようなものです。
なので、いろいろな操作が可能です。

文字列は""で括ります。

 "Hello Java World!"

printlnできます。

 System.out.println("Hello Java World!");

足し算もできます。

 System.out.println("This is " + "a test.");

変数にも代入できます。変数の種類はStringです。オブジェクト指向の用語で説明すると、Stringクラスのインスタンスとしてworldを定義したということです。クラスは設計図、雛形、金型のようなもので、インスタンスはそれから作成された実体のようなものです。

 String world = "Hello Java World!";

-演習6

最初に作ったHello.javaプログラムを、String変数 worldという変数に代入してから表示するプログラムに書き換えてみましょう。

解答例:

 class Hello {
 public static void main (String args[]) {
         String world = "hello java world!";
         System.out.println(world);
         }
 }

-演習7

--コマンドの引数はarg[0], arg[1] ... などにString型の配列としてプログラムに引き渡されます。
--二つの引数を与えたときに、それが+でつないで表示されるプログラムを作りましょう。


http://gyazo.com/8159f78165e17781a7110de3763c833c.png


ヒント


--以下は引数一つを表示するだけのサンプルです。これをもとに考えてください。
--arg[0]とarg[1]をprintlnの中で+でつないで表示すれば良いです。

 class ArgsTest {  
 public static void main (String args[]) {
 	System.out.println(args[0]);
         }
 }


できてしまった人は以下をお願いします。


このプログラムで、引数が2個未満の場合はエラーになります。
2個未満の場合には、2個引数を描いてくださいというメッセージを出すよう変更しましょう。
.length関数でargsの長さを知ることができます。
if文はC言語と同じです。

 if(args.length < 2) {
 } else {
 }

というように書けます。

--------------

***配列 [#e846fded]

C言語では小規模な配列を使う場合、静的に確保した配列をよく使っていたと思います。
Javaでは、システムからメモリー確保して動的に確保した配列を使うのが一般的です。
C言語でもmalloc()関数でメモリーを確保したことがあると思います。
例えばint型の変数3個分のメモリを確保して、それをint型を示すポインターに入れて、配列として使いました。

 //C言語での例です:
 int *p;
 *p = (int *)malloc(sizeof(int)*3);


Javaでも同じことをやります。
システムにお願いして、必要な量の配列を格納するメモリー領域を確保してもらいます。そのコマンドがnewです。


まずは配列の変数を定義して、次にnewコマンドで必要なメモリー領域を確保して、それが返すメモリーアドレス(に相当する値)を配列の変数に入れます。メモリーアドレスに相当する数値は、C言語ではポインターと言いましたが、Javaでは参照と言います。

 int[] x;  (配列を参照する変数を定義する)
 x = new int[3];   (int3個ぶんのメモリー領域をnewコマンドで取得して参照をxに代入する)
 
こうすると、プログラムの中からx[0]=1;とかx[2]=x[0];などと操作してこの配列を利用できます。

1行でまとめて書くこともあります。

 int[] x = new int[3];

演習3

要素が100個のintの配列x[0]からx[99]を作って、それに1,2,3,4....,100という数字を入れて、さらにそれらをprintlnで表示するプログラムを作りましょう。先ほどのVartest.javaを改造して作ってください。for文で値を入れて、for文で表示してください。for文の使い方はC言語と同一です。

ヒント:


 class Vartest {  
 public static void main (String args[]) {
    
    //配列を定義します。
    //(略)
    
    
    //for文で値を入れます
    for(int i=0; i<100; i++) {
    //(略)
    }
    
    //for文で表示します
   for(int i=0; i<100; i++) {     //(略)
    }
 }



---------------------

**第3章「変数」 [#xc22f04b]

***Javaにおける基本データ型 [#n3c4e251]

-整数型
--byte (1バイト。-128から127)
--short (2バイト。-32,768から32767)
--int (4バイト。-2,147,483,648から2,147,483,647)
--long (8バイト。明確に数値で指定する場合は、x = 20L; のように表記。-9,223,372,036,854,775,808から9,223,372,036,854,775,807)
--char (1文字を表す。メモリー上のサイズは色々。''でくくる。x = 'A'など。)
-浮動小数点型
--float (4バイトで表す浮動小数点。重力加速度なら9.80665のように表記。)
--double (8バイトで表す高精度な浮動小数点。光速なら2.99792458e+8dのように表記。)
-論理型
--boolean (trueかfalseのどちらかの値をとる。 x = true; など。)

C言語と違い、整数型のサイズが明確に決められました。char型は、C言語では1バイトでしたが、Javaでは1文字を表します。なので、コードによって1バイトだったり、多バイトだったりします。C言語では論理型がないので、charやintで代用していました。0とか1を代入してました。Javaでは専用のboolean型が用意されました。

-演習1

先に作ったHello.javaを参考にVartest.javaというプログラムを作りましょう。
以下では、byte型変数を定義して、それを表示しています。
変数名は変えても良いです。
printlnの中では、文字列を連結しています。Javaでは文字列を+で連結できます。

 class Vartest {  
 public static void main (String args[]) {
 	int x = 42;
         System.out.println("byte value x =" + x);
         }
 }

これをもとに、short, int, long, char, float, double booleanの変数を全て追加して表示をしてください。intとcharを追加するなら、以下のようにします。変数名と代入する値は好きなものを使ってください。char型は漢字も試してください。ただしchar型は、1文字だけです。

 class Vartest {  
 public static void main (String args[]) {
 	byte x= 42;
 	int x1=  123456;
 	char name = '椎';
         System.out.println("byte value x =" + x);
         System.out.println("int value x1 =" + x1);
         System.out.println("char value name =" + name);
         }
 }

解答例:
 
 class Vartest {  
 public static void main (String args[]) {
	byte x_byte = 42;
	int x_int = 12345;
	short x_short = 123;
	long x_long = 12345678;
	char x_char = '椎';
	float x_float = 123.4f;
	double x_double = 3.14d;
	boolean x_boolean = true;
        System.out.println("byte value x_byte = " + x_byte);
        System.out.println("short value x_short = " + x_short);
        System.out.println("int value x_int = " + x_int);
        System.out.println("long value x_long = " + x_long);
        System.out.println("char value x_char = " + x_char);
        System.out.println("float value x_float = " + x_float);
        System.out.println("double value x_double = " + x_double);
        System.out.println("boolean value x_boolean = " + x_boolean);
        }
 }


-演習2

以下のように、整数型の変数に文字を代入して値を表示すると、文字コードが表示できる。
あなたのイニシャルを表す英文字の文字コードを表示するプログラムを作成しなさい。また、あなたの氏名の最初の文字(漢字やひらがな)についても調べなさい。

 int myInitialCode1 = 'S', myInitialCode2 = '椎';
 System.out.println(myInitialCode1);
 System.out.println(myInitialCode2);

------------------


- 次に簡単なウィンドウを出してみましょう。

授業の最後の方で紹介する,Swingというフレームワークを使ってウィンドウを出してみます.


 import javax.swing.JFrame;
 public class SimpleWindow {
 
        public static void main(String argv[]) {
                JFrame f = new JFrame("私が作った最初の窓");
                f.setSize(200,100); 
//                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setVisible(true);
        }
 
 }

これを&#x53;impleWindow.javaという名前で保存して、

 javac SimpleWindow.java
 java SimpleWindow

とタイプしてコンパイル/実行します。
このプログラムは,ウィンドウのクローズボタンを押しても終了しません.
プログラムを停止するには,ターミナルでコントロール-cを押します.

#ref(How2Java/simplewindow.png)



*** 超簡単なプログラム(hello world)を作ってみる [#v4ccc293]


- ターミナルから、vi Hello.javaとかemacs Hello.javaとかpico Hello.javaとかタイプしたり、
もしくは、cotEditerを起動して作成します。

- ここで、以下のようなプログラムを書いてみます。

 class Hello {  
 public static void main (String args[]) {
         System.out.println("hello java world!");
         }
 }

http://siio.jp/gyazo/20121004010107.png


- これをHello.javaという名前で保存します。lsやcatコマンドで確認しましょう。cat Heくらいをタイプして、あとはタブキーを使って補完機能を利用してください。

 $ ls
 Hello.java
 $ cat Hello.java 
 class Hello {  
 public static void main (String args[]) {
         System.out.println("hello java world!");
         }
 }

今は、Hello.javaファイルが一つしかありません。これをコンパイルします。

 $ javac Hello.java  (コンパイルする)
 
 コンパイルに成功するとHello.classというファイルができているはずです。lsコマンドで確認します。
 
 $ ls
 Hello.class	Hello.java

これはjavaコマンドで動作します。javaはインタープリータです。

 $ java Hello      (実行する。.javaなどの拡張子は不要)
 hello java world!   (結果)




----------



**javaのマニュアル [#beafbfad]

//http://sdc.sun.co.jp/java/docs/j2se/1.5.0/ja/docs/ja/api/index.html
//http://java.sun.com/javase/ja/6/docs/ja/api/index.html
//http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/index.html
//http://docs.oracle.com/javase/jp/6/api/
http://docs.oracle.com/javase/jp/8/docs/api/index.html


***参考図書(去年までは教科書でした) [#d5f8ad25]

http://gyazo.com/de3288074dae1c75f6df4ef3c0b9b3d4.png

http://www.amazon.co.jp/dp/4883732258/

前半はこの内容で進めますので、手元にあると便利です。

*** この講義の目的 [#l5592b29]
+Javaでプログラムする
+オブジェクト指向の概念を理解してプログラミングする
+GUIプログラミングをする

*** この講義の順序 [#gcf48d66]
+Javaになれる(C言語などのプログラミング手法の復習)
+オブジェクト指向について理解する
+GUIプログラミングについて理解する(イベント駆動)
+お絵描きプログラムを作ってみる

*** 成績評価 [#c732dbb9]
+お絵描きプログラムの完成度,作り込み
+毎回の宿題の達成(参考程度)
+出席状況(参考程度)

***単位を出す条件 [#k4e326f7]
//**欠席状況

+ 最終課題のお絵描きプログラムで最低限お願いした機能を実装してください。
+ 3/4以上出席してください。(欠席は3回まで)欠席4回で自動的に不可になります。
(公欠、忌引などは欠席にしませんので連絡ください。病欠、電車遅延の遅刻は確認できるものを提出してください。)

//欠席3回以下なら不可にはなりませんが、成績が下がるかもしれません。

//以下に欠席状況を示します。
//ので、心当たり無ければ連絡ください。
//(病欠、公欠、忌引などは0になっているはずですが間違っていたら連絡ください。)

***授業用のフォルダを作る [#l5df9663]

授業の内容を入れておくフォルダを作ってください。Documentsの中にjavaというようなフォルダを作ると良いです。

***出席表明アプリケーション [#s026a135]

以下のアプリケーションで、授業開始に出席表明してもらいます。皆さんがクリックし終わったら、締め切ります。それまでにクリックできない人は遅刻とします。

- http://siio.jp/IamAttending.zip

#ref(http://siio.jp/gyazo/b1128c100d39263a8480428af2d05da0.png,200x200)

- ダウンロードしてzipを開くと、フォルダになっているかもしれません。その中にあるIamAttendingというアプリを使います。
- 初めて起動する時は、右クリックして、「開く」ボタンを選んでください。
- 今後の授業でも最初に使いますのでわかりやすいところに置いてください。


//|学籍番号|10/4|10/11|10/25|11/8|11/15|11/22|11/29|12/6|12/13|12/20|1/10|合計|
//|1720501|0|0|0|0|0|0|0|0|0|0|0|0|


** 出来上がったプログラムの提出方法 [#bd9cbbf8]
- フォルダを作ってその中にjavaファイルとclassファイル
//と、取扱説明書ファイルと、それ以外に必要なファイルがもしあればそれら
を入れてください。
フォルダの中のclassファイルをダブルクリックしたらプログラムが起動することを確認してください。
-このフォルダに名前を付けてください。フォルダの名前は、「出席番号+氏名(ローマ字の姓名)+必要ならばバージョン番号の数字」にしてください。たとえば17020999siioitiro01のように。なお全部半角英数字でお願いします。
-このフォルダを圧縮してください
--フォルダを選択してファイルメニューから圧縮を選択します
-圧縮したファイルを以下の手順で
 /home/isstaff/siio/Public/Drop Box/.
に提出してください。ターミナル.appからなら
 cp 123456siioitiro.zip /home/isstaff/siio/Public/Drop\ Box
としてください。ファインダーからなら、メニューから「移動」「フォルダへ移動...」を選んで
以下のように入力して、移動ボタンを押して、そこに現れるドロップボックスホルダに、ドラッグアンドドロップしてください。

http://siio.jp/gyazo/dropbox.png
--書き込み専用なので確認できないけどokですかという意味のダイアログが出るかと思いますが問題ありません。
-レポート提出用フォルダは書き込み専用で見ることができません。アップロードできたかどうか不安でしたら教員まで質問してください。
//-授業中でしたら、[[ココを見ると:http://siio.jp/lecture/java_report.html]]一覧をみることができます。
-同じ名前のフォルダを投げ込むと、エラーになります。ということで新しいバージョンができたら別の名前のフォルダを作って提出し直してください。(フォルダ名最後に数字をつけてください)




*ヒューマンインタフェース2019年度前期 [#o618d6d1]



**ヒューマンインタフェースのレポート [#fa42ea61]

提出は任意です.もし良いレポートを提出いただけたら出席点の加算に使用します.

-締め切り2019年8月31日土曜日
-形式分量:A4, ページ数は1-2ページ程度
-提出先・提出方法:PDFにしてsiio@is.ocha.ac.jpまでメール添付で送付
-メール表題:ヒューマンインタフェースレポート: 17205XX

メールの標題は「ヒューマンインタフェースレポート: 17205XX」としてください。数字部分は出席番号です。
提出いただいた方はこのページでお知らせします。提出してしばらく経つのに、 自分の番号がなかなか表示されない場合は,受付されていないかもしれません.もう一度催促してください 
(提出を確認出来るよう締め切りより早めに提出していただくことをお勧めします)。

//提出状況は、この下に、学籍番号と受理日で案内します。
//もし、学籍番号が公表されたくない場合は、確認用の秘密の仮名を提出メールの中でお知らせください。
//学籍番号の代わりにその名前を使います。


//|学籍番号|受理日|
//| 1720505 |2019年8月30日|
//| 1720514 |2019年8月31日|
//| 1720525 |2019年8月26日|
//| 1720529 |2019年8月24日|
//| 1720535 |2019年8月31日|
//| 1720543 |2019年8月31日|
//| sunny |2019年8月31日|

//sunny  = 1720534
//|1620515|2018年8月|
//|1620520|2018年8月|


***レポートの課題 [#c9d0add0]

-身の回りの携帯機器、家電製品、機械製品、コンピュータソフトウェア、 道具、日用品、調度品、設備などから、 使いにくいと思われる道具を見つけ出して説明してください。
-そして、それがなぜ使いにくいのかを、 授業で説明した、 制約、マッピング、Affordance、モデル、 エラー対策、 標準化、直接操作、メタファー、モードなどの用語を使って分析してください。 (全部の用語を使う必要は無い)
-また,自分ならこのように設計して使いやすくするというアイディアを、 これも授業で使った用語を交えて、述べてください。




**出席状況 [#te5cda59]

学部「ヒューマンインタフェース」は出席重視の授業です.そのため70%以上出席お願いします. 授業回数が13回ですので,欠席が3回を超えた場合は単位が出ません. 以下に授業全体の欠席状況を示す予定です。
//しておきます. 
欠席回数は成績に大きく影響しますので、間違いありましたら至急お知らせください.
//公欠届のある日は出席としてあります。

//|学籍番号|4月12日|4月19日|5月17日|5月24日|5月31日|6月7日|6月14日|6月21日|6月28日|7月5日|7月12日|7月19日|7月26日|欠席回数|
//|1620415|出|出|欠|出|出|欠|欠|欠|出|出|出|出|出|4不可|
//|1620501|出|出|出|出|出|出|出|出|出|出|出|出|出|0|


** 講義開催予定 [#p8ec1788]

-4/11
-4/18
-4/25
-4/27 休講(出張)
-5/9 休講(学会出張)
-5/16
-5/23 
-5/30
-6/6
-6/13
-6/20
-6/27
-7/4
-7/11 休講
-7/18
-7/25
-8/1 試験週間のため授業はありません


**宿題 [#pb8621ca]

下のリンク先のソースコードをコンパイルして、応答速度を図るプロログラムを作ってください。これを使って、みなさんの応答速度を図って、次回(2019年5月16日)の小テスト用紙(A5サイズ)で報告してください。

http://lab.siio.jp/index.php?CSL11HCI#k497ebbd


//**宿題 [#x69779a5]
//
//***GUI黎明期のPC性能を調べてください(2018.4.19) [#ba9db6ff]
//-GUI黎明期PCのCPU名、CPUクロック、メモリ容量、画素数を調べてください
//--現在,Windows を使っている人は,最初の Windows が出荷された 1985 年当時に使われていたIBM PC/AT
//--Mac OS Xを使っている人は,1984に出荷された最初の Macintosh 
//-今あなたが使っているコンピュータと比較してください. 
//-次回の授業(5/17)最初に配布するA5サイズの用紙に各自で記入して提出してもらいます


//**宿題
//
//***人の反応速度を測定するプログラムを作って測定してください。(2014.4.24) † [#jbad7411]
//-連休明けの授業(5/15)の開始時に、A4, 1枚(両面印刷でも可)で提出してください。
//--用紙の上辺に学籍番号、学年、氏名を1行で書いておいてください。
//-C 言語では,次のようなプログラムで、”hit now”という文字を表示した後、リターンキーが押されるまでの時間を測定できます。
//--http://siio.jp/hci/hitnow.c
//--このプログラムは固定時間(5秒)後にhit nowが表示されます。乱数を使って表示までの時間を変える改良をしてもらっても良いです。(改良したらそのこともレポートしてください)
//-これによりあなたの応答速度を複数回実測して、人の応答速度が 300ms 程度であることを確認してください。 
//-また個人差や年齢などで結果は変わるかもしれません。周りの複数の人に被験者になってもらって調査しても面白いかもしれません。
//-また何度も測定することで、習熟して速度が向上したり、それでも限界があったり、さらには、逆に疲労により速度が低下することがあるかもしれません。
//--そのような現象が観察できたら、これも報告してください。(教科書8章の学習曲線を参考にしてください)

**教科書 [#ta8dbb5f]
http://ec2.images-amazon.com/images/I/51SsP4P1UiL._SL500_AA300_.jpg

http://www.amazon.co.jp/dp/4781912605/

**授業資料 [#s6bf1fc3]
+http://siio.jp/lecture/humaninterface/HCI_c1.ppt.pdf
+http://siio.jp/lecture/humaninterface/HCI_c2.ppt.pdf
+http://siio.jp/lecture/humaninterface/HCI_c3.ppt.pdf
+http://siio.jp/lecture/humaninterface/HCI_c4.ppt.pdf
+http://siio.jp/lecture/humaninterface/HCI_c5.ppt.pdf
+http://siio.jp/lecture/humaninterface/HCI_c6.ppt.pdf
+http://siio.jp/lecture/humaninterface/HCI_c7.ppt.pdf
+http://siio.jp/lecture/humaninterface/HCI_c8.ppt.pdf
+http://siio.jp/lecture/humaninterface/HCI_c9.ppt.pdf
+http://siio.jp/lecture/humaninterface/HCI_c10.ppt.pdf

(授業開始直前や直後に差し替えされている可能性があります。)

**教科書サポートページ [#b385f64d]

-http://lab.siio.jp/index.php?CSL11HCI




//**宿題:ボタンを押すたびに点灯/消灯を繰り返す(トグルする)プログラム (2015/7/17提出) [#a9dc7742]
//
//以下は、Arduinoの2ピンに接続された押しボタンスイッチを押すとLEDが点灯するプログラムです。これを改造して、押し//ボタンスイッチを押すたびに、点灯/消灯を切り替えるプログラムを作ってください。
//ちなみにHIGHとLOWはintの値で、int型の変数で保存することができます。
//
// int outpin=13; //An LED is connected to ping 13
// int inpin=2;  //A switch is connected to pin 2
// 
// void setup() {                
//   // initialize the digital pin as an output and input.
//   pinMode(outpin, OUTPUT);     
//   pinMode(inpin, INPUT);
// }
// 
// void loop() {
//   if ( digitalRead(inpin) == HIGH) {
//     digitalWrite(outpin, LOW);   // set the LED on
//   }
//   else {
//     digitalWrite(outpin, HIGH);    // set the LED off
//   }
//   delay(30);              // wait for 30 msecond
// }


//**宿題:人の反応速度を測定するプログラムを作って測定してください。(2015.5.1) [#f5834458]
//-連休明けの授業(5/8)の開始時に、A5, 1枚に書いて提出していただきます。
//-C 言語では,次のようなプログラムで、”hit now”という文字を表示した後、リターンキーが押されるまでの時間を測定でき//ます。
//--http://siio.jp/hci/hitnow.c
//--このプログラムは固定時間(5秒)後にhit nowが表示されます。
//-- 乱数を使って表示までの時間を変える改良をしてもらっても良いです。(改良したらそのこともレポートしてください)
//-これによりあなたの応答速度を実測して、人の応答速度が 300ms 程度であることを確認してください。(複数回実測して平均とってもらえるとさらに正確ですね)
//
//







------
このページについてのお問い合わせはsiio@is.ocha.ac.jpまで。

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS