음 제목 만 보면 조금 문장이 햇갈릴수도 있다.
풀어서 이야기하면 필드(맴버변수)를 public 으로 선언하지말고 접근자 메소드를 만들어라. 라는거다.

우리는 보통 C 나 C++ 을 기본적으로 배운다.
일반적으로 처음에는 변수, 함수 에대해서 배우고 구조체, 포인터 에 대해서 배우게 될것이다. 이때까지만 해도 접근 제한자 라는 놈은 없었다. C++에서도 클레스를 사용하고 java를 배우기 시작하면서 접근 제한자 라는놈을 만나게 되는데 처음 객체지향 프로그래밍을 접하게 되면 닥치고 public 혹은 아무것도 안적거나 를 시전하게된다.

이것은 이전 항목에서도 설명한 캡슐화라는 개념에서 상당히 위험한 요소이다.
솔직히 이런부분은 써보면 안다. 라고 말하는게 설명하는 입장에서 가장 쉬운 설명인데 좀 이야기를 풀어보도록 하자.

일단 가장 쉽게 Point 라는 x,y 좌표를 표시하는 클레스를 만들었다고 하자.

class Point{
	public int x;
	public int y;
	
	public Point(int x, int y) {
		this.x = x;
		this.y = y;
	}
}

이렇게 만들었다고 해보자 그냥 x와 y좌표를 바꾸기 위해서는 Point.x=10, point.y=20 이런식으로 해주면된다.
근데 이게 위험하니까 
class Point{
	private int x;
	private int y;
	
	public Point(int x, int y) {
		this.x = x;
		this.y = y;
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}
	
}

이렇게하자? 뭐야 이 개떡같이 길기만하고 의미 없는 코드들은?
이라는 감상평을 들을수 있겠다. 솔직히 개인적으로도 뭐하려고 저딴짓을 하나 싶기도 하다. 근데 우리가 저걸 더 확장해서 Vector 이라는 클레스를 만들어 보도록 하자.
Vector은 방향과 크기가 있다. 라는것을 익히 알것이다. (모른다면 한번쯤 찾아보는것도 좋을것이다. 그래픽 관련된 프로그래밍 할때 종종 쓰인다.)
 
class Vector{
	public double x;
	public double y;
	public double angle;
	public double value;
	
	public Vector(double x, double y) {
		this.x = x;
		this.y = y;
		angle=Math.atan2(x, y);
		value=Math.sqrt(x*x+y*y);
	}
	
}

벡터에 대해서 클레스를 만들었는데 여기에는 x,y 를 표시하는 방향, 크기 와 그것을 계산해서 원점으로부터 각도와 크기를 구하고자 한다. 그러면 몇몇의 연산이 좀더 들어가야된다.
x,y 를 이용해서 각과 크기를 구해서 angle과 value라는 변수에 저장을 했다. 이것을 이용해서 다음과 같은 코드를 짜보았습니다.


class Vector {
	public double x;
	public double y;
	public double angle;
	public double value;

	public Vector(double x, double y) {
		this.x = x;
		this.y = y;
		angle = Math.atan2(x, y);
		value = Math.sqrt(x * x + y * y);
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return String.format("x : %f, y : %f, angle : %f, value : %f",x,y,angle,value);
	}
	public static void main(String[] args) {
		Vector v=new Vector(1, 1);
		System.out.println(v);
		v.x=2;
		System.out.println(v);
	}
}

x : 1.000000, y : 1.000000, angle : 0.785398, value : 1.414214
x : 2.000000, y : 1.000000, angle : 0.785398, value : 1.414214
결과는 이렇게 나옵니다.
이해가 잘안되는 분을 위해 좀더 설명하겠습니다.
처음에 x=1,y=1 이용해서 객체를 생성하면 각은 45도 즉 pi/4 의 값을 가지고 크기는 루트2 입니다.
근데 여기서 x를 2로 바꾸었다면 x=2,y=1 이기 때문에 각은 대충 25도쯤 크기는 루트3 이 됩니다.
이게 제가 보여드릴수 있는 가장 쉬운 예입니다. 그렇다면 이것을 어떻게 처리해야 하느냐?

class Vector {
	private double x;
	private double y;
	private double angle;
	private double value;

	public Vector(double x, double y) {
		this.x = x;
		this.y = y;
		angle = Math.atan2(y, x);
		value = Math.sqrt(x * x + y * y);
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return String.format("x : %f, y : %f, angle : %f, value : %f",x,y,angle,value);
	}
	public static void main(String[] args) {
		Vector v=new Vector(1, 1);
		System.out.println(v);
		v.setX(2);
		System.out.println(v);
	}
	
	/**
	 * x,y 를 angle와 value를 이용해서 다시 계산한다.
	 */
	private void calcXY(){
		x=value*Math.cos(angle);
		y=value*Math.sin(angle);
	}
	/**
	 * angle, value 를 x와 y를 이용해서 다시 계산한다. 
	 */
	private void calcAV(){
		angle = Math.atan2(x, y);
		value = Math.sqrt(x * x + y * y);
	}
	
	public double getX() {
		return x;
	}

	public void setX(double x) {
		this.x = x;
		calcAV();
	}

	public double getY() {
		return y;
	}

	public void setY(double y) {
		this.y = y;
		calcAV();
	}

	public double getAngle() {
		return angle;
	}

	public void setAngle(double angle) {
		this.angle = angle;
		calcXY();
	}

	public double getValue() {
		return value;
	}

	public void setValue(double value) {
		this.value = value;
		calcXY();
	}
}
이렇게 바꾸면 됩니다.
일단 코드가 무지막지하기 길어졌습니다. 이때문에 이런걸 싫어하는 사람도 있습니다만은..

하여튼 이렇게 코드가 완성되면 x와 y, angle, value 가 각각 수정될때마다 영향을 받는 다른 값들을 동시에 수정을 하고 외부에서 그 값을 각각의 값들이 말도 안되는 형태를 취하고 있는것을 피할수 있게됩니다.
x : 1.000000, y : 1.000000, angle : 0.785398, value : 1.414214
x : 2.000000, y : 1.000000, angle : 0.463648, value : 2.236068
실행해보면 이렇게 제대로된 결과를 뽑아줍니다.

추가로 뭘 변경 하면 좋을까요. angle 이 조금 마음에 안드네요. 우리가 보기 좋은것은 각도 로 표시되는거지 라디안이 아니거든요.
이때 각도용 set을 하나 만들어줍니다. 그리고 toString 도 좀 수정하면 좋겠네요.
//추가
public void setDegree(double degree){
	setAngle(Math.toRadians(degree));
}
//수정
public String toString() {
	return String.format("x : %f, y : %f, angle : %f, value : %f",x,y,Math.toDegrees(angle),value);
}


 

public static void main(String[] args) {
	Vector v=new Vector(1, 1);
	System.out.println(v);
	v.setX(2);
	System.out.println(v);
	v.setDegree(60);
	v.setValue(2);
	System.out.println(v);
}


그리고 원래 만들었던 main 을 이렇게 바꾸어 보았습니다.
x : 1.000000, y : 1.000000, angle : 45.000000, value : 1.414214
x : 2.000000, y : 1.000000, angle : 26.565051, value : 2.236068
x : 1.000000, y : 1.732051, angle : 60.000000, value : 2.000000

출력은 이렇게 나옵니다.

하여튼 여러모로 접근자 메소드(setter, getter)로 클레스를 구성해놓으면 나중이 편합니다.

추가. Getter,Setter 만드는 방법1

여기서 골라서 체크한뒤에 확인 누르시거나

아니면 코드 중간에 set 를 적은뒤 컨트롤+스페이스, get 적은뒤 컨트롤+스페이스 를 하게되면

이런식으로 나옵니다 방향키로 골라서 엔터 하면 되요
Posted by 동적할당
: