JAVA プログラミング 入門

JAVAのプログラミングについて初歩から解説します。まずは、mainメソッド、変数、演算、if文、for文、while文、メソッド、配列など。続いて、メソッドを複数構成して、プログラムを作成(非オブジェクト指向プログラミング)、しばらく後になると思いますが、オブジェクト指向プログラミングを解説します。 クラスの構成、コンストラクター、継承、・・・、など、本格的OOP(Object Oriented Programming)を解説します。

JAVA PROGRAMMING入門 目次

 

  1. Java 非オブジェクト指向プログラミング
  2. JAVAは非オブジェクト指向プログラミングにも大変適しています。 全てのメソッド及びローカル以外の変数、配列をstatic 宣言すると、 オブジェクトを設計、作成することなく大きなプログラムでも書けます.
    1. Java Compilerのインストール
    2. Java 最初のプログラム
    3. Java 変数、演算、標準出力
    4. Java データの入力(キーボード)、実数
    5. Java ゼロで割る, データの型変換
    6. Java  if 文ー 条件成立のときの処理、複文
    7. Java if else:二つの場合分け
    8. Java if else if else:三つ以上の場合分け
    9. Java switch 便利な場合分け
    10. Java for文 代入演算子など
    11. Java: 二重のfor文, break文, continue文, printf
    12. Java: while: 繰り返し, 配列1
    13. Java: do while, 配列2、配列変数
    14. Java: 配列の初期化、多次元配列
    15. Java: 引数なしと値渡しの引数を持つメソッド
    16. Java: メソッドからメソッドを呼び出す
    17. Java: 参照渡しの引数を使うメソッド
    18. Java: 参照渡しの引数を使うメソッド: 色々な場所にあるデータとメソッド
    19. Java: 数値積分による円の面積の計算
  3. Java: オブジェクト指向プログラミング
    1. Java: 初めてのオブジェクト作成(Constructorを書かない)
    2. Java:コンストラクタ--引数の扱い方
    3. Java:コンストラクタ---thisの使い方
    4. Java:クラスの継承 Override, superの使い方
    5. Java: クラスの継承 toStringメソッドの継承と使い方(オーバーライド)
    6. Java: 簡単なアクセス制限とカプセル化
    7. Java: アクセス制御1
    8. Java: 例外処理1
    9. Java: 例外処理2 例外クラスの作成, throws, throw
    10. Java: 抽象クラスと抽象メソッド
    11. Java: インタ-フェースと抽象クラス
    12. Java:クラス群の設計ーabstract class, interface を使った継承と実装の組合わせの可能性
    13. Java: package-パッケージ間のACCESS
    14. Java: テキストファイル処理: 文字ストリーム
    15. Java: CSV FILE (データがコンマで区切られたファイル)を扱う
    16. Java: クラス・ライブラリの作り方と使い方
    17. Java: スレッド(プロセスの中の簡易プロセス)
    18. Java: スレッド の応用(簡単な分散処理の真似事)

JAVA PROGRAMMING 入門 TOP へ

Java: スレッド の応用(簡単な分散処理の真似事)

Java: スレッド の応用(簡単な分散処理の真似事)

1から100までの整数の合計をスレッドに分けして計算させ、手分けして計算した部分を合計することにより、総合計を求めるプログラムです。Thread1は1から32までThread2は33から67、Thread3は68から100までの合計をそれぞれ計算し、main で集計して表示する。

これらのスレッドの処理をネットワークにより別々のコンピュータに担わせると小さな分散コンピューティングになる.
Proo18_1.java

class CompThread extends Thread {
	private String name;
	private int start,end,result;
	CompThread(String n,int s, int e){
		name=n; start=s; end=e;
	}
	int getResult() {return result;}
	public void run() {
		int s=0;
		for(int i=start;i<=end;i++) s +=i;
		result=s;
	}
}
class Proo18_1 {
	public static void main(String args[]) {
		CompThread[] t = new CompThread[3];
		t[0]=new CompThread("thread0",1,32);
		t[1]=new CompThread("thread1",33,67);
		t[2]=new CompThread("thread2",68,100);
		for(int i=0;i<t.length;i++) t[i].start();
		try{
			for(int i=0;i<t.length;i++) {
				t[i].join();
			}
		}
		catch(InterruptedException e) {}
		int su=0;
		for (int i=0;i<t.length;i++){
			su+=t[i].getResult();
		}
		System.out.println("1 から 100 の和は "+su);
	}
}
/*
1 から 100 の和は 5050
*/				

JAVA PROGRAMMING 入門 TOP へ

Java: スレッド(プロセスの中の簡易プロセス)

スレッドには以下のようなものである。
1)スレッドとは一つのプロセスの中に作ることがで
きる簡易プロセス
2)スレッドはプロセスに所属する。
3)プロセスのメモリなどのリソースを共有する。動
作が軽い。軽量級のプロセスといわれる。
4)複数のスレッドを一つのプロセスに持つことがで
きる。
5)JVM(Java virtual machine)でスレッドを管理する。

スレッドは以上の性質を持っているため、上手くプログラムを構成すれば、効率のよいプログラムを作成できることが期待でされる。

スレッドの作成の仕方は二つある。

Ⅰ. Threadを拡張したクラス(スレッドクラス)を作る方法
1) Threadクラスを拡張したクラスを作る。
2) Threadにはrunメソッドがあるので、それをオーバーライドする。それが、スレッドの動作内容である。
3) スレッドクラスによりオブジェクトを作成し、start()メソッドでスレッドをスタートさせる。

次のプログラムはこの方法で作成したスレッドのプログラムである。mainで二つのスレッドを作成し、それらをスタートさせている。mainも一つのスレッドである。
Proo17_1.java

class Book extends Thread{
   private String title;
   public Book(String title){
      this.title = title;
   }
   public void run(){
      for(int i=0; i<3; i++){
         System.out.println(title + " is being read.");
      } 
   }
}
class Proo17_1{
   public static void main(String args[]){
      Book a = new Book("Book1");
      a.start();
      Book b = new Book("Book2");
      b.start();
      for(int i=0; i<3; i++){
         System.out.println("main() is running.");
      } 
   }
}
/*
main() is running.
main() is running.
main() is running.
Book1 is being read.
Book2 is being read.
Book1 is being read.
Book2 is being read.
Book1 is being read.
Book2 is being read.
*/

Ⅱ.Runnableインターフェースを使う方法
1) Runnableインターフェースを実装したクラスのオブジェクトを作成する。実装するとき、runメソッドを実装する。それが、スレッドの動作内容である。
2) そのオブジェクトをパラメータとして、Threadのオブジェクトを作る。それが、スレッドのオブジェクトである。
そのスレッドオブジェクトのstartメソッドを起動する。

次のプログラムはこの第二の方法で作成したスレッドのプログラムである。mainで二つのスレッドを作成し、それらをスタートさせている。mainも一つのスレッドである。
Proo17_2.java

class Book implements Runnable{
   private String title;
   public Book(String title){
      this.title = title;
   }
   public void run(){
      for(int i=0; i<3; i++){
         System.out.println(title + " is being read.");
      } 
   }
}
class Proo17_2{
   public static void main(String args[]){
		Thread a=new Thread(new Book("Book1"));
		a.start();
		Thread b=new Thread(new Book("Book2"));
		b.start();
      for(int i=0; i<3; i++){
         System.out.println("main() is running.");
      } 
   }
}
/*
main() is running.
main() is running.
main() is running.
Book2 is being read.
Book1 is being read.
Book2 is being read.
Book1 is being read.
Book2 is being read.
Book1 is being read.
*/

JAVA PROGRAMMING 入門 TOP へ

Java: クラス・ライブラリの作り方と使い方

クラス・ライブラリの作り方と使い方
1) ライブラリにしたいプログラム(クラス)をディレクトリ構造(カレント・ディレクトリの下)を作ってそこに置く.
2) 全てのプログラムをコンパイルする.
3) 以下の命令を実行
jar cf myjar.jar ディレクトリ構造のルート
myjar.jarというファイルがライブラリになる
4) myjar.jarを適当な場所に置く.
例えばC:¥
5) C:¥myjar.jarを環境設定のCLASSPATHに書き、必要であれば”.;”を追加する.

例題で説明します。
今から作るライブラリには以下の四つのクラスがある。ただし、最初の三つをライブラリとし、4番目のクラスは作ったライブラリをテスト的に使うクラスである。

1) Abst_Class1(パッケージmylib.abst_class1の中)
  Class1の親クラス
  コンストラクタAbst_Class1がある
2) Class1(パッケージmylib.class1の中)
  メソッド show1, show2がある
  コンストラクタ Class1があり
  Abst_Class1をcallする

3) Seisuu(パッケージmylib.seisuuの中)
  static メソッドwaがある.

4) Proo16_1(namelessパッケージの中)
mainメソッドがある
  Class1, Abst_Class1などを使う 
  Seisuuクラスのメソッドwaを使う。

図Package_treeは以上を図示したものである。

f:id:Kurokawa_Tomio:20190716192226p:plain
図Package_tree
以下にそれぞれのクラスのソースを示す。
Abst_Class1.java

package mylib.abst_class1;
interface inter1{
   void show1();
   void show2();
}
public abstract class Abst_Class1 implements inter1
{   
   private int num1;
   protected Abst_Class1(int n){this.num1=n;}
   public void show1(){
      System.out.println("show1 num1=" + num1 );
   }
   public abstract void show2();
}

説明:
1行 パッケージ名
2行 inter1にはメソッドが二つある。
10行 コンストラクタAbst_Class1は別パッケージの子クラスから使われるのでprotectedにしてある。
Class1.java

package mylib.class1;
import mylib.abst_class1.*;
public class Class1 extends Abst_Class1 {
   private String s1;
	public Class1(int n, String s){
    	super(n);
      this.s1 = s;
   }
   public void show2(){
	show1();
      System.out.println("show2 s1="+s1);
   }
}

説明:
2行 このクラスは パッケージmylib.abst_class1を使う。
6行 親クラスのコンストラクタを使っている。
Seisuu.java

package mylib.seisuu;
public class Seisuu{
	public static int wa(int m, int n){
		int s=0;
		for(int i=m;i<=n;i++){
			s+=i;
		}
		return s;
	}
}

説明:
1,2行 Seisuuクラスはmylib.seisuuパッケージにある。
3行  メソッドwaはstaticである。

Proo16_1.java

import mylib.abst_class1.*;
import mylib.class1.*;
import mylib.seisuu.*;
class Proo16_1{
   public static void main(String args[]){
      Abst_Class1 f1 = new Class1(1, "Tokyo");
	f1.show2();
	System.out.println("Seisuu.wa(1,10)="+Seisuu.wa(1,10));
   }
}
/* 出力
show1 num1=1
show2 s1=Tokyo
Seisuu.wa(1,10)=55
*/

説明:
1,3行 三つのパッケージをimport
8行  メソッドwaはSeisuuクラスのクラスメソッドである。

それぞれのクラスをコンパイルするには
>javac mylib\abst_class1\Abst_Class1.java
>javac mylib\class1\Class1.java
>javac mylib\seisuu\Seisuu.java
>javac Proo16_1.java

実行:
>java Proo16_1
show1 num1=1
show2 s1=Tokyo
Seisuu.wa(1,10)=55

JAVA PROGRAMMING 入門 TOP へ

JAVA: CSV FILE (データがコンマで区切られたファイル)を扱う

CSV FILEはエクセルなどでもよく使われている。Proo15_1.javaはCSV FILE(a.txt)の各行の合計を計算し、それを各行の末尾に追加するプログラムである。ただし、元のCSV FILEはそのまま残り、結果ファイル(b.txt)が新しくできる。

Proo15_1.java

/* CSV FILE の各行の合計を 各行の末尾に付加する  */
import java.util.*;
import java.io.*;
class Proo15_1 {
	public static void main(String args[]) throws IOException
	{
		int t=0,i;
		BufferedReader br=
			new BufferedReader(new FileReader("a.txt"));
		PrintWriter pw =
			new PrintWriter(new BufferedWriter(new FileWriter("b.txt")));
                String str;
		while((str=br.readLine())!=null){
			t=0;i=0;
			StringTokenizer st = new StringTokenizer(str, ",");
			while(st.hasMoreTokens()) {
				String s = st.nextToken();
				i=Integer.parseInt(s);
				t=t+i;
				pw.print(i+",");
			}
			pw.println(t);
		}
		br.close();
		pw.close();
	}
}
/* 
FILE a.txt(input data)
1,2,3,4,5,6,7,8,9,10
4,5,6
7,8,9

FILE b.txt(結果ファイル)
1,2,3,4,5,6,7,8,9,10,55
4,5,6,15
7,8,9,24
*/

説明:
2行 StringTokenierというclassがあるjava.utilとうパッケージをimportしている。
3行 BufferedReaderなどのioのライブラリclassを使うため。
15行 読み込んだ一行(str)をStringTokenizerにセットしている。つまり、カンマで区切られたデータを一つ一つ取り出すため。
16行 まだデータ(トークン)があるかチェックする。
17行 データを一つ取り出す。
18行 文字列の整数をintに変換する
20行 intデータと”,”をファイルに書き出している。
22行 一行の合計値をファイルに書き込んでいる。
30から32行 入力データ
35から37行 出力データ

JAVA PROGRAMMING 入門 TOP へ

Java: テキストファイル処理: 文字ストリーム

JAVAでは、ストリームという抽象的なものに対して入出力を行う。テキストファイルを扱うときは、文字ストリームを使う。文字ストリームにはいくつかのクラスがライブラリとして用意されているのでそれを使って、テキストの読み書きをする。入出力に必要なクラスはjava.ioパッケージにある。
プログラムではそれらのクラスを先ずimportする。


文字ストリームのクラス:
Reader
InputStreamReader
FileReader
BufferedReader

Writer
OutputStreamWriter
FileWriter
BufferedWriter
PrintWriter

それらを組み合わせて、入出力の適切なオブジェクトを作り、入出力処理を行う。手順は以下の通りです。

① ストリームを作成する(開く)
② データを書き込む、または読み込む
③ ストリームを閉じる

よく使う入出力の方法:

テキストファイルの入力:
BufferedReader br=
new BufferedReader(newFileReader("ファイル名"));

br.readLine();により一行づつ読む

テキストファイル出力:
PrintWriter pw =
new PrintWriter(
new BufferedWriter(new FileWriter("ファイル名")));

pw.println();により一行づつ書く

標準入力:
BufferedReader br =new BufferedReader( new InputStreamReader(System.in));

br.readLine()により一行づつ読む

標準出力
System.out.println();により一行づつ書く

例1:テキストファイルをコピーする
Proo14_1.java
起動:   >java Proo14_1

/*   TEXT FILE 処理    */
/* Copy text file to another file*/
import java.io.*;
class Proo14_1 {
	public static void main(String args[]) throws IOException
	{
      String str;
		BufferedReader br=
			new BufferedReader(new FileReader("a.txt"));
		PrintWriter pw =
			new PrintWriter(new BufferedWriter(new FileWriter("b.txt")));
		while((str=br.readLine())!=null){
			pw.println(str);
			System.out.println(str);
		}
		br.close();
		pw.close();
	}
}
/*
123
1234
*/

説明:
3行 java.oiパッケージをimportしている。
5行 IOExceptionが起こる可能性があるので、その処理をmainを起動したところに任せている。
8,9行 BufferedReaderのオブジェクトを作成している。これでa.txtのテクストファイルを読む準備ができたことになる。
10,11行 PrintWriterオブジェクトを作成している。これで、テキストファイルを書く準備ができたことになる。
12行 brオブジェクトのreadLineメソッドを使って一行読み、それがnullでなければ、pwオブジェクトのprintlnメソッドを使って読み込んだ一行をファイルb.txtに書き込んでいる。さらに同じ一行をディスプレーにも表示している。
16,17行 brとpwオブジェクトを閉じている。


例2:キーボードより入力して、テキストファイルに書き込む
Proo14_2.java
起動:   >java Proo14_2 c.txt

/* TEXT FILE 処理  */
/* keyboard to  file  parameter at start*/
import java.io.*;
class Proo14_2 {
	public static void main(String args[]) throws IOException
	{
      String str;
		BufferedReader br =
			new BufferedReader(new InputStreamReader(System.in));
		PrintWriter pw =
			new PrintWriter(new BufferedWriter(new FileWriter(args[0])));
		while((str=br.readLine())!=null){
			pw.println(str);
		}
		br.close();
		pw.close();
	}
}
/*
abcdefgh
abcde
abc
*/

説明:
11行 args[0]はプログラム起動時のパラメタである。この場合ファイル名(c.txt)である。
20から22行 キーボードより与えたデータである。最後の行の次にcontrolCによりファイルの終わりとしている。ここで、キーボードからの入力修了
このデータはファイルc.txtに書き込まれている。

JAVA PROGRAMMING 入門 TOP へ

Java: テキストファイル処理: 文字ストリーム

JAVAでは、ストリームという抽象的なものに対して入出力を行う。テキストファイルを扱うときは、文字ストリームを使う。文字ストリームにはいくつかのクラスがライブラリとして用意されているのでそれを使って、テキストの読み書きをする。入出力に必要なクラスはjava.ioパッケージにある。
プログラムではそれらのクラスを先ずimportする。


文字ストリームのクラス:
Reader
InputStreamReader
FileReader
BufferedReader

Writer
OutputStreamWriter
FileWriter
BufferedWriter
PrintWriter

それらを組み合わせて、入出力の適切なオブジェクトを作り、入出力処理を行う。手順は以下の通りです。

① ストリームを作成する(開く)
② データを書き込む、または読み込む
③ ストリームを閉じる

よく使う入出力の方法:

テキストファイルの入力:
BufferedReader br=
new BufferedReader(newFileReader("ファイル名"));

br.readLine();により一行づつ読む

テキストファイル出力:
PrintWriter pw =
new PrintWriter(
new BufferedWriter(new FileWriter("ファイル名")));

pw.println();により一行づつ書く

標準入力:
BufferedReader br =new BufferedReader( new InputStreamReader(System.in));

br.readLine()により一行づつ読む

標準出力
System.out.println();により一行づつ書く

例1:テキストファイルをコピーする
Proo14_1.java

/*   TEXT FILE 処理    */
/* Copy text file to another file*/
import java.io.*;
class Proo14_1 {
	public static void main(String args[]) throws IOException
	{
      String str;
		BufferedReader br=
			new BufferedReader(new FileReader("a.txt"));
		PrintWriter pw =
			new PrintWriter(new BufferedWriter(new FileWriter("b.txt")));
		while((str=br.readLine())!=null){
			pw.println(str);
			System.out.println(str);
		}
		br.close();
		pw.close();
	}
}
/*
123
1234
*/

説明:
3行 java.oiパッケージをimportしている。
5行 IOExceptionが起こる可能性があるので、その処理をmainを起動したところに任せている。
8,9行 BufferedReaderのオブジェクトを作成している。これでa.txtのテクストファイルを読む準備ができたことになる。
10,11行 PrintWriterオブジェクトを作成している。これで、テキストファイルを書く準備ができたことになる。
12行 brオブジェクトのreadLineメソッドを使って一行読み、それがnullでなければ、pwオブジェクトのprintlnメソッドを使って読み込んだ一行をファイルb.txtに書き込んでいる。さらに同じ一行をディスプレーにも表示している。
16,17行 brとpwオブジェクトを閉じている。


例2:キーボードより入力して、テキストファイルに書き込む
Proo14_2.java

/* TEXT FILE 処理  */
/* keyboard to  file  parameter at start*/
import java.io.*;
class Proo14_2 {
	public static void main(String args[]) throws IOException
	{
      String str;
		BufferedReader br =
			new BufferedReader(new InputStreamReader(System.in));
		PrintWriter pw =
			new PrintWriter(new BufferedWriter(new FileWriter(args[0])));
		while((str=br.readLine())!=null){
			pw.println(str);
		}
		br.close();
		pw.close();
	}
}
/*
abcdefgh
abcde
abc
*/

説明:
11行 args[0]はプログラム起動時のパラメタである。この場合ファイル名(c.txt)である。
20から22行 キーボードより与えたデータである。最後の行の次にcontrolCによりファイルの終わりとしている。ここで、キーボードからの入力修了
このデータはファイルc.txtに書き込まれている。

Java: package-パッケージ間のACCESS

Java: package-パッケージ間のACCESS

ここで扱うプログラムは以下の三つのソースファイルに分かれている。

1) Abst_Class1.java
このソースはabst_class1というパッケージに属する。
そこにはinterfaceが二つあり、inter1,inter2である。さらに、Abst_Class1というクラスが存在する。このクラスは2)のClass1に継承される。
2) Class1.java
このソースはclass1というパッケージに属する。ここにはAbst_Class1を継承したClass1というクラスが存在する。
3) Proo13_1.java
このソースはproo13_1というパッケージに属する。ここにはProo13_1というクラスが存在し、上記の二つのクラスを使う。


packageとはクラスを分類するjava の命令である。ソースプログラムの先頭で以下のように指定する。

package abst_class1;

そうすると、2行目以降のクラスがabst_class1 というパッケージに属することになる。パッケージはディレクトリーと一致させて作る。

作成したソースプログラムのファイル名をAbst_class1.javaとし、 abst_class1というパッケージに属する。カレントディレクトリの下にabst_class1というディレクトリを作り、その中にAbst_class1.javaのファイルを置く。そして、以下の操作をするとコンパイルされる。

>javac abst_class1\Abst_cass1.java

Abst_cass1.javaの中身は以下の通りである。

package abst_class1;
interface inter1{
   void show1();
   void show2();
}
public abstract class Abst_Class1 implements inter1
{   
	private int num1;
	protected Abst_Class1(int n){this.num1=n;}
   	public void show1(){
      System.out.println("show1 num1=" + num1 );
   }
	public abstract void show2();
}

説明:このパッケージにはインターフェースinter1があり、そこにメソッドが二つある。またAbst_Class1というabstractクラスがある。メソッドshow1はここで実装されている。しかし、メソッドshow2はabstractのままである。二つのメソッドはインターフェースから来ているので、publicにしてある。 Abst_Class1は別パッケージにある子クラスClass1から呼び出される予定であるので、protectedとしてある。num1は最大保護するためprivateとしてある。

続いて、class1のディレクトリを作りそこにClass1.javaを置き、以下のようにコンパイルする

>javac class1\Class1.java

Class1.javaの中身は以下の通りである。

package class1;
import abst_class1.*;
public class Class1 extends Abst_Class1 {
   private String s1;
	public Class1(int n, String s){
    	super(n);
      this.s1 = s;
   }
   public void show2(){
		show1();
      System.out.println("show2 s1="+s1);
   }
}

説明:
1行 ここにあるクラスは全てclass1というパッケージに属する。
2行 abst_class1のクラスを使うので、その中のパッケージをimportしている。*はその中のすべてのクラスを意味する。
5行 このコンストラクタは別パッケージから使われるので、publicにしている。勿論、Class1もpublicである。
9行 show2を実装している。

importについて:
これは指定されたパッケージの中のクラスをあたかも当該パッケージに移したごとく振舞えるということです。*の代わりにクラス名を指定するとそのクラスだけを移したかのようになるということです。

続いて、proo13_1のディレクトリを作りそこにProo13_1.javaを置き、以下のようにコンパイルする

>javac proo13_1\Proo13_1.java

Proo13_1.javaの中身は以下の通りである。

package proo13_1;
import abst_class1.*;
import class1.*;
class Proo13_1{
   public static void main(String args[]){
      Abst_Class1 f1 = new Class1(1, "Tokyo");
	   f1.show2();
   }
}
/* 出力
show1 num1=1
show2 s1=Tokyo
*/

説明:
2,3行 二つのパケージをimportしている。
末尾には実行結果がある。

全てコンパイルできたところで、以下のように実行する。
>java proo13_1.Proo13_1
実行結果はProo13_1.javaの末尾にある。

ACCESS修飾子protectedに関するACCESS制御は以下の二つの表の通りです。

f:id:Kurokawa_Tomio:20190712133840p:plain
図Proo13_1_ACCESS1
f:id:Kurokawa_Tomio:20190712133943p:plain
図Proo13_1_ACCESS2

JAVA PROGRAMMING 入門 TOP へ

Java: クラス群の設計ーabstract class, interface を使った継承と実装の組合わせの可能性

Java: クラス群の設計ーabstract class, interface を使った継承と実装の組合わせの可能性

プログラムを設計していると、いろいろなクラスを作成することになる。このクラス群をどのように作成するかを考えてみたいと思います。今、特に、具体的問題があるわけではないので、とりあえず、どのような可能性があるかを検討したいと思います。

洗い出した幾つかのクラスは似ていることが多く共通部分があることが多い。その共通部分をクラス継承の親クラス、またそれぞれのクラスを子クラスと考える。また、クラスのメソッドを整理しまとめ、インターフェースとし、それに入れるべきメソッドをアブストラクトメソッドとして用意するとする。

以下はそれらの可能性を探るプログラムコードです。

interface inter1{
   void show1();
   void show2();
}
interface inter2{
   void show3();
   void show4();
}
interface inter3{
   void show5();
   void show6();
}
interface inter4{
   void show7();
   void show8();
}
abstract class Abst_Class1 implements inter1
{   
	private int num1;
	Abst_Class1(int n){this.num1=n;}
   public void show1(){
      System.out.println("show1 num1=" + num1 );
   }
	public abstract void show2();
}
class Class1 extends Abst_Class1 {
   private String s1;
	Class1(int n, String s){
    	super(n);
      this.s1 = s;
   }
   public void show2(){
		show1();
      System.out.println("show2 s1="+s1);
   }
}
class Class2 extends Abst_Class1 {
   private String s2;
	Class2(int n, String s){
    	super(n);
      this.s2 = s;
   }
   public void show2(){
		show1();
      System.out.println("show2 s2="+s2);
   }
}
abstract class Abst_Class2 implements inter2
{   
	private int num2;
	Abst_Class2(int n){this.num2=n;}
   public void show3(){
      System.out.println("show3 num2=" + num2 );
   }
	public abstract void show4();
}
class Class3 extends Abst_Class2 {
   private String s3;
	Class3(int n, String s){
    	super(n);
      this.s3 = s;
   }
   public void show4(){
		show3();
      System.out.println("show4 s3="+s3);
   }
}
class Class4 extends Abst_Class2 {
   private String s4;
	Class4(int n, String s){
    	super(n);
      this.s4 = s;
   }
   public void show4(){
		show3();
      System.out.println("show4 s4="+s4);
   }
}
class Class5 implements inter3{   
	private int num3;
   private String s5;
	Class5(int n,String s){this.num3=n;this.s5=s;}
   public void show5(){
      System.out.println("show5 num3=" + num3);
   }
   public void show6(){
 		show5();
      System.out.println("show6 s5="+s5);
   }
}
class SuperClass6{   
	protected int num4;
	SuperClass6(int n){this.num4=n;}
}
class Class6 extends SuperClass6 implements inter4{   
   private String s4;
	Class6(int n, String s){super(n);this.s4=s;}
   public void show7(){
      System.out.println("show7 num4="+num4);
   }
   public void show8(){
 		show7();
      System.out.println("show8 s4="+s4);
   }
}
class Class7{   
	private int num5;
   private String s5;
	Class7(int n,String s){this.num5=n;this.s5=s;}
   void show9(){
      System.out.println("show9 num5=" + num5);
   }
   void show10(){
 		show9();
      System.out.println("show10 s5="+s5);
   }
}
class Proo12_1{
   public static void main(String args[]){
      Class1 f1 = new Class1(1, "Tokyo");
      Class2 f2 = new Class2(2, "Yokohama");
		Class3 f3 = new Class3(3,"Nagoya");
		Class4 f4 = new Class4(4,"Gifu");
		Class5 f5 = new Class5(5,"Osaka");
		Class6 f6 = new Class6(6,"Fukuoka");
		Class7 f7 = new Class7(7,"Kumamoto");
      f1.show2();
      f2.show2();
      f3.show4();
      f4.show4();
      f5.show6();
      f6.show8();
      f7.show10();
   }
}
/* 出力
show1 num1=1
show2 s1=Tokyo
show1 num1=2
show2 s2=Yokohama
show3 num2=3
show4 s3=Nagoya
show3 num2=4
show4 s4=Gifu
show5 num3=5
show6 s5=Osaka
show7 num4=6
show8 s4=Fukuoka
show9 num5=7
show10 s5=Kumamoto
*/

1.Class1からClass4
これらはインターフェースを実装したabstract classを経て作成したクラスです。それぞれのabstract classはそこで実装したメソッドとフィールドを持ち、子クラス(Class1からClass4)はそこで実装したメソッドと追加したフィールドを持っています。このようにすると、二段階の実装ができることになります。早くから仕様が明らかになったものを先に実装するということです。フィールドはすべてprivate にして保護しています。

2.Class5
このクラスはinter3の二つのabstract メソッドを実装しています。abstractメソッドは同じ名前で別のクラスに別機能のメソッドとして実装することができるので、show5, show6はこの名前で別のクラスに実装してもよい。

3.Class6
これは単に継承と実装を同時に行う例です。まず、SuperClass6を作成しておいて、それを継承しinter4を実装しています。SuperClass6はnum4を設定するアクセスメソッドを持っていないので、privateにできず、やむを得ず、num4をprotectedにしています。
4.Class7
このクラスは抽象クラスやインターフェースを使わないクラスです。

JAVA PROGRAMMING 入門 TOP へ

Java: インタ-フェースと抽象クラス

クラスのようなものである。
インターフェースの形は以下のようになる。

interface インターフェース名{
型名 フィールド1= 式;
...
型名 フィールドm= 式;

戻り値の型 メソッド名1();
...
戻り値の型 メソッド名n();
}

フィールドはすべて(実質的に)public static final、つまり定数。メソッドはすべてpublic abstractと同じ。

interfaceはその実装クラスで実装して使う
class 実装クラス implements インターフェース名
{
}

実装クラス はinterfaceのフィールドとメソッドを受け継ぎ、メソッドはすべて定義しなければならない。

インターフェースのimplementsとは:
抽象クラスのメソッドをオーバーライドするのとほぼ同じ(別クラスに同じ名前で別機能のメソッドを持たせる)。
ただし、フィールドの値を変えることは不可。
複数のクラスを継承することはできないが
複数のinterfaceを実装することはできる。

class クラス名implements interface名,
interface名、・・・・interface名


抽象クラスとインターフェイス
類似点:
1)オブジェクトを作れない。
コンストラクターは書けるが、それ自身でオブジェクトは作れない
2)抽象クラスはサブクラスに、インターフェイスは実装クラスにメソッドの実装を要請する。

相違点:
1)インターフェイスはクラス階層のどのクラスにもくっ付くが、抽象クラスはクラス階層の一箇所に位置する。
2)抽象クラスは抽象メソッドが1以上。フィールドは定数でなくてもよい。インターフェイスは全てのメソッドが抽象メソッド、全てのフィールドが定数。
3)抽象クラスの抽象メソッドはpublicまたは protected。インターフェースのメソッドは全てabstract & public。


図Proo11_1_srcにプログラム例を示す。

f:id:Kurokawa_Tomio:20190707212009p:plain
図Proo11_1_src
1から4行 インターフェースの定義。二つの抽象メソッドが書かれている。
5から16行 実装クラスProBook
フィールドは全てprivate。
10から12行 sbook定義されている。これはコンストラクタで使われている。
13から15行 displayが実装されている。

17から27行 実装クラスTextBook
ProBookとほぼ同じになっている。

JAVA PROGRAMMING 入門 TOP へ

以下にソースを二つ示す。

interface scratch {
	void sbook(String title, int page);
	void display();
}
class ProBook implements scratch{
	private String title;private int page, category;
   public ProBook(String title, int page, int category){
		sbook(title,page);this.category=category;
   }
	public void  sbook(String title, int page){
		this.title=title;this.page=page;
	}
   public void display(){
		System.out.println(" [ProBook: "+title+","+page+","+category+"]");
	}
}
class TextBook implements  scratch{
	private String title;private int page,school;
   public TextBook(String title, int page, int school){
		sbook(title,page);this.school=school;
   }
	public void  sbook(String title, int page){
		this.title=title;this.page=page;
	}
   public void display(){
		System.out.println(" [TextBook: "+title+","+page+","+school+"]");
   }
}
public class Proo11_1{
   public static void main(String args[]){
		ProBook a; TextBook b;
		a=new ProBook("Introduction to C++",300,5);
		b=new TextBook("Beginner's Java",400,3);
		a.display();b.display();
   }
}
// [ProBook: Introduction to C++,300,5]
// [TextBook: Beginner's Java,400,3]

Java: 抽象クラスと抽象メソッド

抽象クラス、抽象メソッドは以下のような定義又は特徴を持つ。
抽象クラス:
 1)抽象メソッドをもつ
 2)abstract修飾子がつく
 3)オブジェクトを作成できない
 4)子クラスでそのメソッドを定義することを期待、つまり、オーバーライド。
抽象メソッド:
 1)処理内容の定義されていないメソッド
 2)abstract修飾子がつく

つまり、抽象クラスは拡張を期待したクラスであり、抽象メソッドはオーバーライドを期待したメソッドである。

例えば、abstractクラスは以下のような形になる。

abstract class XXX {
フィールド1;フィールド2;...
メソッド1;メソッド2; ...

abstract 戻り値メソッド名();
……
abstract 戻り値メソッド名();

}

つまり、abstractメソッド以外は通常のクラスと同じ、しかし、一つ以上の動作定義のないabstractメソッドが存在する。

クラス設計では複数の似たクラスを設計する場合が多い。そのとき共通部分を親クラス又はabstractクラスとし、それぞれの残りの部分を子クラスとする考え方がある。abstractメソッドは名前だけが共通部分で残りはそれぞれの子クラスで違っているということである。

abstractクラスにはコンストラクターが存在し得る。しかし、オブジェクトは作成できない。従って、親クラスとして、そのクラスのオブジェクトが必要な場合はそのクラスをabstractにはできない。

図Proo10_1_srcはabstractクラスの説明のための例である。

f:id:Kurokawa_Tomio:20190706133137p:plain
図Proo10_1_src
1から8行 abstract class Book
7行 displayは内容が未定義
9から17行 Bookを拡張したProBook
10行 子クラスの追加フィールド
11から13行 ProBookでBookのdisplayを実装している(オーバーライド)
18から26行 Bookを拡張した子クラスTextBook
19行 子クラスの追加フィールド
23から25行 TextBookでBookのdisplayを実装
30行 ProBookのオブジェクトを作成
31行 TextBookのオブジェクトを作成
32行 二つのオブジェクトのdisplayを起動
35から36行 二つオブジェクトの内容が表示されている。

JAVA PROGRAMMING 入門 TOP へ

以下にソースを二つ示す。

abstract class Book{
	String title;
	int page;
   public Book(String title,int page) {
     this.title = title;this.page=page;
   }
	abstract void display();
}
class ProBook extends Book{
   private int category;
   public ProBook(String title, int page, int category){
		super(title,page);this.category=category;
   }
   public void display(){
		System.out.println(" [ProBook: "+title+","+page+","+category+"]");
	}
}
class TextBook extends Book{
   private int school;
   public TextBook(String title, int page, int school){
		super(title,page);this.school=school;
   }
   public void display(){
		System.out.println(" [TextBook: "+title+","+page+","+school+"]");
   }
}
class Proo10_1{
   public static void main(String args[]){
		Book a,b;
		a=new ProBook("Introduction to C++",300,5);
		b=new TextBook("Beginner's Java",400,3);
		a.display();b.display();
   }
}
// [ProBook: Introduction to C++,300,5]
// [TextBook: Beginner's Java,400,3]

Java: 例外処理2 例外クラスの作成, throws, throw

Java: 例外処理2

例外処理の方法には以下の二つある
1)例外が発生した場合、Try catchでそれを受け
取り処理する。
2)Try catchを書かないで、そのメソッドに
throws 例外クラスと書いて、処理を、それ
をコールしたところに任せる。

今回は上記の二つを一緒に使い,さらに独自の例外オブジェクトを作成使用するような仕掛けの例外処理を扱う。図Proo9_1_srcはそのための例である。

f:id:Kurokawa_Tomio:20190702182039p:plain
図Proo9_1_src
図Proo9_1_srcについて:

2行 例外オブジェクトを作成するためのクラスである。

12から15行 例外オブジェクトを作成、例外を起こすメソッド(cause_except)である。このメソッドはthrows節が付いていて、例外の処理をメソッドを呼んだところに任せるようにしている。13行で例外オブジェクトを作り、15行でそれを投げている。投げた例外は8行の
catchで受け取られ、そのメッセージを出している。

6行 mainのtryブロックの中で例外を起こすメソッド(cause_except)を呼んでいる。

JAVA PROGRAMMING 入門 TOP へ

以下にソースを二つ示す。

/*例外処理2   例外クラスの作成, throws, throw */
class AException extends Exception{};
class Proo9_1 {
	public static void main(String[] args) {
		try {
			cause_except();
		}
		catch(AException ae){
			System.out.println(ae+"を受け取りました。");
		}
	} 
	static void cause_except() throws AException {
		AException ae = new AException();
		System.out.println(ae+"を投げます。処理は任せます");
		throw ae;
	}
}
/*
AExceptionを投げます。処理は任せます
AExceptionを受け取りました。
*/

Java: 例外処理1

例外とは、エラーのような状態である。例えば、ゼロで除算を行う場合、配列の範囲を超えてアクセスした場合などである。このような場合、プログラムを止めないで、特別の処理をすると都合がよい場合がある。

今回はその例外を扱う。
ゼロによる除算を例とする。ゼロで割ることはできないないので、エラー状態になることが予想される(ArithmeticException: / by zeroの例外)。

図Proo8_1_srcはその例外が起こるプログラムである。

f:id:Kurokawa_Tomio:20190702110207p:plain
図Proo8_1_src
実行すると、11,12行で示されるようなメッセージが出てプログラムは止まる。このままでも、ゼロによる割り算であるから、やむを得ないと分かり、そのようなことのないように対処できる。例えば、bをゼロとしないなど。

しかし、JAVAには例外に対して特別に対処する方法がある。図Proo8_2_srcはtry-catch-finallyという方法で対処している。

f:id:Kurokawa_Tomio:20190702110323p:plain
図Proo8_2_src

この方法は例外が起こりそうな部分をtryブロックで囲み、例外が起きたときシステムから送られくる例外オブジェクトを受け取る例外参照変数(ae)を用意しておき、その後の処理をcatchブロックに書いておく。そのようにすれば、どのような例外が起こったのかが分かり、更に例外が発生した直後にプログラムを止めてしまわないで、必要な処理ができる。finallyブロックはなくてもよい。書いておくと例外が起きても、起きなくてもそのブロックは処理される。try-catch-finally構造は以下のように書く。

try{
 例外が起きる可能性がある部分
}
catch(例外参照変数の型 例外参照変数){
 例外が起きたときの処理
}
finally{
 例外の有無にかかわらず実行される処理
}

JAVA PROGRAMMING 入門 TOP へ

以下にソースを二つ示す。

/* 例外処理             */
class Proo8_1 {
	public static void main(String[] args){
		int a=5,b=0,c=100;
		System.out.println("a="+a+" b="+b+" c="+c);
		c=a/b;
	}
}
/*
a=5 b=0 c=100
Exception in thread "main" java.lang.ArithmeticException: / by zero
        at Proo8_1.main(Proo8_1.java:6)
*/
/* 例外処理             */
class Proo8_2 {
	public static void main(String[] args){
		int a=5,b=0,c=100;
		try{
			System.out.println("a="+a+" b="+b+" c="+c);
			c=a/b;
		}
		catch(ArithmeticException ae){
			System.out.println(ae+"の例外が発生しました");
			System.out.println("a="+a+" b="+b+" c="+c);
		}
		finally{
			System.out.println("例外のあるないに関わらずfinallyは処理される");
		}
	}
}
/*
a=5 b=0 c=100
java.lang.ArithmeticException: / by zeroの例外が発生しました
a=5 b=0 c=100
*/

Java: アクセス制御

JAVAのアクセス制限はどこからアクセスするかによって違ってくる。何処からには3種類ある。それは以下の通りである。
1)パッケージの外からのアクセス
2)同じパッケージ内のあるクラスから別のクラスへのアクセス
3)同じクラス内でのアクセス
パッケージとは、一つ又は複数のクラスをまとめたものである。従って、JAVAのプログラムはパッケージ群によりできている。

この3種類のアクセスをクラスとメンバーの2段階で制御するのがJAVAのアクセス制御である。これまでに学習したパッケージは無名パッケージだけであるので、ここでは無名パッケージでのアクセス制御について解説する。つまり、同じパッケージ内の別クラスからのアクセスについてである
(Java: Access from a Different Class within a Package )。

クラスのアクセス修飾子はpublicと「指定なし」がある。メンバーの修飾子にはpublic, protected, 「指定なし」, privateがあるが、
protectedについては後程学習Java: package-パッケージ間のACCESSする。

図Proo7_1_ACCESS1は異なるパッケージ間でのアクセス制限である。クラスもフィールドもpublicでないとアクセスできない。

f:id:Kurokawa_Tomio:20190701144315p:plain
図Proo7_1_ACCESS1
図Proo7_1_ACCESS2は同じパッケージ内でのクラス間のアクセスである。メンバーがpublic又は「指定なし」であれば、クラスはpublicでも「指定なし」でもよい。
f:id:Kurokawa_Tomio:20190701144408p:plain
図Proo7_1_ACCESS2
クラス内でのアクセスは常に可能である。

図Book_no_modi、図Book2_public,図Proo7_1_srcはソースプログラムである。これらは同じパッケージ内でのアクセス制御を説明するためのものである。三つのクラス:Book, Book2, Proo7_1は全て「名前なし」のパッケージ内にある。Bookはpublicでないが、Book2はpublicである。これらは別々にコンパイルされる。

f:id:Kurokawa_Tomio:20190701144518p:plain
図Book_no_modi
f:id:Kurokawa_Tomio:20190701144605p:plain
図Book2_public


Bookについて:
このクラスは修飾子なし」である。
displayはpublic、Bookコンストラクタは「修飾子なし」である。
これらはProo7_1クラスから呼ばれ、正常に動作している。同じパッケージのあるクラスから別の「修飾子なし」クラスへのアクセスは正常である。

BooK2について:
これはpublicクラスである。
display2はpublic、Book2コンストラクタは「修飾子なし」である。
これらもProo7_1クラスから呼ばれ、正常に動作している。同じパッケージの別のpublicクラスへのアクセスは正常である。

上記はメソッドだけについて、チェックしたが、フィールドに関しても同じことが言えると考える。

以上、同じパッケージ内の別クラスへのアクセスについてチェックしたが、「修飾子なし」Bookとprivate Book2のフィールドは全てprivateとして保護した。そのうえで、メソッドを「修飾子なし」とpublicでチェックし、すべて正常に動作した。アクセス不可に関しては、チェックができていないが、private メソッドは別クラスからは動かない、またはコンパイル時にエラーとなる。

同じパッケージ内の別クラスからのアクセス制御はカプセル化の考え方でOKであると考える。つまり、フィールドはprivateとして、メソッドはpublicまたは「修飾子なし」としてよいが、
できるだけprivateとして保護するという考え方で問題ないと考える。
JAVA PROGRAMMING 入門 TOP へ
以下に三つのソースを示す。

class Book {
	private String title;
	private int page;
	private void set_Book(String title,int page){
		this.title=title;this.page=page;
	}
	private void display(){
		System.out.println("title="+title+", page="+page);
	}
	public Book(String title, int page){
		set_Book(title,page);
	}
}
public class Book2 {
	private String title;
	private int page;
	private void set_Book2(String title,int page){
		this.title=title;this.page=page;
	}
	public void display2(){
		System.out.println("title="+title+", page="+page);
	}
	Book2(String title, int page){
		set_Book2(title,page);
	}
}
/*アクセス制限 同じnameless package 内のアクセス*/
class Proo7_1{
	public static void main(String[] args){
		Book a=new Book("Introduction to Java",500);
		a.display();
		Book2 a2 = new Book2("Introduction to C++",400);
		a2.display2();
	}
}
/*
title=Introduction to Java, page=500
title=Introduction to C++, page=400
*/

Java: 簡単なアクセス制限とカプセル化

プログラム内のフィールドやメソッドは自由に使わせないで、制限を持たせてデータやプログラムを保護することは重要である。JAVAにはそれを行う仕組みが言語の中にある。

特にクラス内のデータとメソッドの保護に関しては、カプセル化という概念で、クラスのメンバー(フィールドとメソッド)をクラス内に閉じ込めて(カプセル化)して保護できる。

カプセル化:
フィールド、メソッドをまとめてクラス入れる。保護したいメンバーをprivate(メンバーやクラスに付ける修飾子)にして勝手にアクセスできないようにする。メンバーはアクセスしないと意味がない、しかしできるだけ保護したいので、特定のメソッドでしかアクセスできないようにしておく。そのメソッドをアクセスメソッドと呼ぶ。

通常以下のような方針でメンバーに修飾子を付ける。
フィールドーーーprivate
メソッド ーーーpublic

privateはclass内以外からのアクセスを不可にするのでフィールドは保護できる。
publicは他の条件が許せばアクセス可を意味する。しかし、できるだけprivateにしてメソッドも保護する方がよいことは言うまでもない。従って、以下のようにしてカプセル化する。

フィールドーーーーーーprivate
アクセスメソッドーーーpublic
その他のメソッドーー-private

図Proo6_1_srcはそのようにして作ったプログラム例である。末尾に実行結果を付けてある。

f:id:Kurokawa_Tomio:20190630172442p:plain
図Proo6_1_src

3,4行 フィールドをprivateにしてクラス内から以外はアクセス不可としている。クラス内からアクセスできないメンバーはない。
5から7行 set_Bookメソッドをprivateにしている。このメソッドはコンストラクタBookだけから使うことにしているからである。クラス内のメソッドからであればprivateメソッドも使える。
8から10行 displayメソッドはpublicにして、クラス外からも使えるようにしてある。アクセスメソッドである。
11から13行 コンストラクタBookはこのクラス唯一のコンストラクタであるからクラス外から使えないといけないのでpublicにしてある。アクセスメソッドである。
17行 コンストラクタBookがクラス外から使用できるでいる。
18行 displayメソッドで表示している。これもpublicである。


今回は主にクラスのメンバーに付ける修飾子について説明しました。アクセス制御については次回に更に解説します。

JAVA PROGRAMMING 入門 TOP へ

以下にソースを貼り付けます

/*アクセス制限とカプセル化*/
class Book {
	private String title;
	private int page;
	private void set_Book(String title,int page){
		this.title=title;this.page=page;
	}
	public void display(){
		System.out.println("title="+title+", page="+page);
	}
	public Book(String title, int page){
		set_Book(title,page);
	}
}
class Proo6_1{
	public static void main(String[] args){
		Book a=new Book("Introduction to Java",500);
		a.display();
	}
}
/*
title=Introduction to Java, page=500
*/