自己啓発マン  2021/01/15更新

JPIN#6 part1


コンストラクタとカプセル化を確認しよう

今回は以下に提示したコードがどのように動いていくのかを解説していく

まずListクラス



public class List {//Listクラス

	private String value;
	private int index;
	private List next;
	
	public List() {//公開のListメソッド
		this.value = null;
		this.index = 0;
		this.next = null;
	}
	
	private List(int index) {//非公開のListメソッドはint型を受け取る
		this();//上記Listメソッドのthisをコピー
		this.index = index;//このクラスのindexに受け取ったindexを代入	
	}
	
	public void add(String value) {//公開のaddメソッドはString型を受け取る
		if(this.value ==  null) {//もしこのクラスのvalueがnullならば以下を実行
			this.value = value;//このクラスのvalueに受け取ったvalueを代入
			return;//このメソッド終わり
		}
		if (this.next == null) {//もしこのクラスのnextがnullだったら以下を実行
			this.next = new List(index + 1);//このクラスのnextに新たに作ったListクラスのListメソッドにindex+1を渡したものの参照アドレスを代入する
		}
		this.next.add(value);//このクラスのnextに書いてあるアドレスのaddメソッドに受け取ったvalueを代入する
	}
	
	public String get(int index) {//公開のgetメソッドはint型を受け取る
		if(this.index == index) {//もしこのクラスのindexと受け取ったindexが同じなら以下を実行
			return this.value;//このクラスのvalueを返す
		}
		if(this.next == null) {//もしこのクラスのnextがnullなら以下を実行
			return null;//nullを返す
		}
		return this.next.get(index);//このクラスのnextに書かれているgetメソッドに受け取ったindexを代入したものを返す
	}
	
	public int size() {//公開のsizeメソッド
		if(this.next == null) {//もしこのクラスのnextがnullなら以下を実行
			return this.index+1;//このクラスのindexに+1して返す
		}
		return this.next.size();//このクラスのnextにあるsizeメソッドを実行して返す
	}


次にこれを動かすMainクラス



public class Main {

	public static void main(String[] args) {
		
		List list = new List();//Listクラスをヒープ領域にコピーしてlistにアドレスをコピー
		list.add("A");//listに書いてあるaddメソッドにAを渡して実行
		list.add("B");//listに書いてあるaddメソッドにBを渡して実行
		list.add("C");//listに書いてあるaddメソッドにCを渡して実行
		
		for (int i = 0; i< list.size(); i++) {//i=0から始まり、listに書いてあるsizeメソッドがiより大きくなるまで以下実行してiに+1
			System.out.println(list.get(i));//listに書いてあるgetメソッドにiを渡して出力
		}	
	}
}


Mainクラスから順に追ってこの二つのコードがどのように動いていっているのかを解説する

まず最初にMainメソッドがスタック領域に乗る

次にListクラスのコピーをヒープ領域に作っている

これが『List list = new List();』の部分だ

このクラスの参照アドレスをlistとしている

次に『list.add("A");』とある

これは先ほど作ったListクラスのaddメソッドにString型の”A”を引数として渡している

ここでListクラスを見てみよう

Listクラスでは最初にprivateで3つの変数が唱えられている

そしてpublicのListメソッドで各値を初期化している

そして引数”A”を受け取ったaddメソッドは実行される

現在、this.valueはnullなのでthis.valueに”A"が代入されてこのメソッドは終了する


Mainメソッドに戻ろう

次に『list.add("B");』では先ほどのListクラスのaddメソッドに今度は"B"を引数として渡している

addメソッドを見ると最初にif文でthis.value ==nullとなっていない(this.value=="A")なので次のif文が実行される

this.next==nullなので『this.next = new List(index + 1);』を実行します

LIstメソッドに引数index+1を渡したもののコピーをヒープ領域に作成して、その参照アドレスをthis.nextに入れます

ここでindex+1を受け取るのはprivateのListメソッドである

privateのListメソッドを実行するとthis.index==1となる

このクラスのアドレスがListクラス①のthis.nextに入った

次に『this.next.add(value);』となっているので

this.next、つまりListクラス②のaddメソッドに引数value("B")を渡す

addメソッドでthis.value==nullなのでthis.valueに”B"が代入されてこのメソッドは終了する


Mainメソッドに戻ろう

『list.add("C");』ではList クラス①のaddメソッドに引数"C"を渡している

上の図でもわかるようにListクラス①のaddメソッドにはA、0、List②のアドレスが書かれているため、

addメソッドの『this.next.add(value);』だけ実行される

Listクラス②のaddメソッドにはB、1、nullが入っているため、『this.next = new List(index + 1);』が実行される

Listクラス②のthis.nextに、Listクラスに引数index+1(ここでindex==1なので、2)を渡したもののコピーをヒープ領域に作りその参照アドレスを記憶する

そしてaddメソッドの『this.next.add(value);』が実行される

Listクラス③はnull、2、nullとなっているのでthis.valueに引数value("C")が代入されてこのメソッドは終了する



Mainメソッドに戻ろう

次にfor文である

『for (int i = 0; i< list.size(); i++)』でListクラス①のsizeメソッドが実行される

Listクラス①のthis.nextはList②のアドレスなので『return this.next.size()』が実行される

Listクラス②のthis.nextはList③のアドレスなので『return this.next.size()』が実行される

Listクラス③のthis.nextはnullなので『return this.index+1;』が実行される

つまりListクラス③のthis.index+1(this.indexは2なので3となる)をして値を返すのである

ここまできてようやくMainメソッドのfor文の条件が0〜3と分かる

※上図のsize(List③)のindexは3に繰り上がりません!2のままです!!誤記です!!)


Mainメソッドのfor文の中を見てみよう

『System.out.println(list.get(i));』となっているのでまずはListクラス①のgetメソッドに引数0を渡そう

ここでListクラス①はA、0、List②となっているのでthis.index==indexとなる

よって『return this.value;』を実行するのでlist.get(0)はAとなる


※上図のsize(List③)のindexは2のままです!!誤記です!!)



次にiは+1されてi==1となり『System.out.println(list.get(i));』を実行

Listクラス①はA、0、List②となっているので『return this.next.get(index);』が実行される

Listクラス②のgetメソッドにindex(1)を渡して実行する

Listクラス②はB、1、List③なのでthis.index==indexとなる

よって『return this.value;』を実行するのでlist.get(1)はBとなる


※上図のsize(List③)のindexは2のままです!!誤記です!!


次にiは+1されてI==2となり『System.out.println(list.get(i));』を実行

Listクラス①はA、0、List②となっているので『return this.next.get(index);』が実行される

Listクラス②のgetメソッドにindex(2)を渡して実行する

Listクラス②はB、1、List③となっているので『return this.next.get(index);』が実行される

Listクラス③getメソッドにindex(2)を渡して実行する

Listクラス③はC、2、nullなのでthis.index==indexとなる

よって『return this.value;』を実行するのでlist.get(2)はCとなる


次にiは+1されてI==3となり『System.out.println(list.get(i));』を実行

Listクラス①はA、0、List②となっているので『return this.next.get(index);』が実行される

Listクラス②のgetメソッドにindex(3)を渡して実行する

Listクラス②はB、1、List③となっているので『return this.next.get(index);』が実行される

Listクラス③getメソッドにindex(3)を渡して実行する

Listクラス③はC、2、nullなのでthis.next==nullとなる

よって『return null;』を実行するのでlist.get(3)はnullとなる



これでMainメソッドは終了する

ちなみに出力結果は

A

B

C

である

〜〜めでたしめでたし〜〜



タイトルとURLをコピーしました