앞선 포스팅에서 조금 개선해서 Immutable을 설명하는걸 구현하려다가 아무의미없이 마무리되어버렸다...

 

학생의 , 이름, 나이, 점수 의 경우보단 학교를 바꾸는 상황을 가정하면 조금더 좋을것 같아 클래스를 추가했다.

 

4개의 클래스 모두 남겨놓는다. 

package thisjavaexam.immutable;

public class Score {
	//점수는 변경을 위해서 클래스를 별도 생
	private int score;
	
	//점수를 호출하기위한 생성자 생성 
	public Score(int score) {
		this.score = score;
	}
	//게터 세터 생성
	public int getScore() {
		return score;
	}
	
	public void setScore(int score) {
		this.score = score;
	}
	
	@Override
	public String toString() {
		return String.valueOf(score);
	}

}
package thisjavaexam.immutable;

public class Student {
	//학생 이름,나이 를 선언 + Score 클래스를 변수로 선언 
	private String name;
	private int age;
	private Score score;
	private School schools; //학교정보를 추가했다. 

	
	//Main클래스에서 사용하기위한 생성자 생성 
	Student(School schools, String  name, int age, Score score){
		this.schools = schools; //학교정보 참조를 추가했다. 
		this.name = name;
		this.age = age;
		this.score = score;
	}
	
	//각각 게터 , 세터 생성 
	public String getName() {
		return name;
	}
	
	public int getAge() {
		return age;
	}
	
	
	public void setName(String name) {
		this.name = name;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
	
	
	
	//name의 문자열이 임의클래스(내가만든 이클래스) 를 호출하면서 발생될 참조값 반환을 방지하기위한 오버라이딩
    // 학교정보를 추가했다.
	@Override
	public String toString() {
		return "학교 : " + schools + ", 학생이름 : " + name + " ,나이 : " + age + " ,점수 : " + score;
	}
	
}
package thisjavaexam.immutable;

public class School {
	//학교를 추가 설정
	private String schools;
	
	public School(String schools) {
		this.schools = schools;
	}
	
	public void setSchools(String schools) {
		this.schools = schools;
	}
	
	public String getSchools(){
		return schools;
	}
	
	@Override
	public String toString() {
		return schools;
	}
}
package thisjavaexam.immutable;

public class StudentMain {

	public static void main(String[] args) {
		//학생정보를 불러오기 위한 생성자 생성 + 학교 생성  
		School schools = new School("서울고등학교");
		Score score1 = new Score(90);
		Score score2 = new Score(100);
		Student std1 = new Student(schools,"홍길동",18,score1);
		Student std2 = new Student(schools,"이몽룡",20,score2);

		
		//Student클래스의 학생이름 나이 정보와, Score의 점수정보를 합쳐 출
		System.out.println("학생1의 정보 = " + std1);
		System.out.println("학생2의 정보 = " + std2);
		
		//private 로 선언되었기 때문에 setter를 사용하
		score2.setScore(80);
		//다시 잘 변경되었는지 확인 
		System.out.println("학생2 점수를 80 점으로 변경");
		System.out.println("학생1의 정보 = " + std1);
		System.out.println("학생2의 정보 = " + std2);
	
		//학생2를 부산고등학교로 전학 보내자
		schools.setSchools("부산고등학교");
		System.out.println("학생2 를 부산고로 전학 ");
		System.out.println("학생1의 정보 = " + std1);
		System.out.println("학생2의 정보 = " + std2);
		
		//학생1을 다시 서울고등학교로 보내려면.. 새로운 생성자를 생성해야한다?
		School schools1 = new School("서울고등학교");  // 생성자 std1의 첫번째 파라미터를 수정해야한다.
		std1 = new Student(schools1,"홍길동",18,score1); // std1 의 재정의
		System.out.println("학생1을 다시 서울고로 전학 ");
		System.out.println("학생1의 정보 = " + std1);
		System.out.println("학생2의 정보 = " + std2);
	}
}

 

 

학생 2의 정보를 부산고등학교로 수정했을 뿐인데, 학생1의 정보까지 모두 부산고등학교로 바뀌어있다.

(이..이걸 구현하려고했던거다 앞선 포스트에...)

 

요 케이스를  해결하기위해 학교정보를 포함한 새로운 객체를 생성해야만 했다. 

School schools1 = new School("서울고등학교"); // 생성자 std1의 첫번째 파라미터를 수정해야한다.

std1 = new Student(schools1,"홍길동",18,score1); // std1 의 재정의

(요건 위의 코드에 붙어있다.)

 

그래서 마지막 정보는 서울,부산 두개의 학교에 나뉘어 처리된걸로 최종처리되었다.

 

당초 고등학교가 final로 선언된 불변객체였다면, 

학생2 정보를 부산고등학교로 바꾸려고 했을때부터 오류가 발생했을것이고, 새로운 객체를 새로 생성해서 작업하도록 강제할 수 있었다.

 

 

 

 

그럼 School 클래스를 불변객체를 사용해보자 

바꿀것은 3가지, 필드를 final선언 , setter는 사용할수없으니 삭제 , 그리고 외부에서 final선언된 학교를 변경하려 면 새로운 객체를 생성하도록 메서드를 만들어준다. 

package thisjavaexam.immutable.real;

public class School {
	//학교를 추가 설정
	private final String schools; //선언값을 final 로 선언했다. 
	
	public School(String schools) {
		this.schools = schools;
	}
	
//	아래 셋터는 final이기에 사용할수 없다 . 삭제 ! 
//	public void setSchools(String schools) {
//		this.schools = schools;
//	}
	
	public String getSchools(){
		return schools;
	}
	
	@Override
	public String toString() {
		return schools;
	}
	
	//외부에서 학교정보를 가져다 쓸 매서드를 만들고, 이 매서드는 new연산자를 통해서 새로운 인스턴스 객체를 만들어 준다.
	public School withSchools(String newSchool) {
		return new School(newSchool);
	}
}

 

그리고 그 메서드를 불러내서, 새로 사용하면된다 .

package thisjavaexam.immutable.real;

public class StudentMain {

	public static void main(String[] args) {
		//학생정보를 불러오기 위한 생성자 생성 + 학교 생성  
		School schools = new School("서울고등학교");
		Score score1 = new Score(90);
		Score score2 = new Score(100);
		Student std1 = new Student(schools,"홍길동",18,score1);
		Student std2 = new Student(schools,"이몽룡",20,score2);

		
		//Student클래스의 학생이름 나이 정보와, Score의 점수정보를 합쳐 출
		System.out.println("학생1의 정보 = " + std1);
		System.out.println("학생2의 정보 = " + std2);
		
		//busanSchool에 대입한다  =  기존 schools의 withSchools매서드를 사용해서 부산고등학교를 생성한다.
		School busanSchool = schools.withSchools("부산고등학교");
		std2 = new Student(busanSchool, std2.getName(), std2.getAge(),score2); // 학생2 정보와 함께 새로 생성한 학교정보를 대입한다. 
		System.out.println("학생1의 정보 = " + std1);
		System.out.println("학생2의 정보 = " + std2);
	}
}

 

마지막으로 불변객체를 써보면서 복습했다.

4일전에 공부했던 내용을 다시 정리하려니 2시간이나 걸렸다 ㅠㅠ.......

 

어휴

+ Recent posts