[Java] 6. 캡슐화와 정보은닉

PYOUNANI·2022년 9월 28일
0

Java

목록 보기
6/14
post-thumbnail

6. 캡슐화와 정보은닉

6-1. 캡술화와 정보은닉


6-1-1. 멤버 접근 제한

지역변수, 매개변수는 해당 메서드 안의 범위 내에서 활용이 된다. 반면 멤버 변수는 꽤 사용하는 것이 길다. 클래스 내에서 활용이 되기 때문이다. 이런 범위를 좁혀 볼 수 있는 것이 private이다.

이처럼 멤버들의 접근을 제한 시켜주는 키워드들을 접근 지정자라고 한다.

  • public
    공용의 멤버이다. 모든 다른 클래스에서도 접근 가능하다.
  • private
    그 클래스 내에서만 접근이 가능하다.
  • default
    같은 패키지 내에서만 접근이 가능하다. 주의해야 할 점은 default는 쓰는 것이 아니라 아무것도 기술하지 않으면 사용이 가능하다.
  • protected
    같은 패키지는 접근 가능하다. 다른 패키지여도 나의 파생 즉 나를 상속받으면 접근 허용하다.

패키지나 상속에 대한 내용은 이후에 배울 것이다.

보통은 클래스나 메서드는 public 그리고 멤버 변수는 private을 쓴다. 물론 반드시 이렇게 사용해야 한다는 의미는 아니다.

6-1-2. 캡슐화

연관되어지는 데이터와 연관되어지는 함수들의 묶음을 객체라고 했었다. 연관된 묶음들이다보니 개별적으로 사용하지 않고 쉽고 안전하게 사용 가능이 가능하다. 이러한 객체의 특징을 캡슐화라고 합니다.
캡술화된 객체를 만든다는 것이 반드시 하나의 클래스로 만들어야 한다는 것은 아닙니다. 캡슐화된 클래스 안에 또 다른 클래스들이 존재할 수 있다.


위의 예시를 보면 원의 반지름은 음수가 될 수 없다. 이처럼 객체를 접근하다보면 객체 외부에서 부적절하게 접근할 수 있다.
그럴땐 정보은닉을 통해 안전하게 사용해볼 수 있다. 변수에 private를 이용해서 객체 내에서만 사용하겠다는 의미로 사용해볼 수 있다. 메서드(Access 메서드)를 통해서만 접근할 수 있게 하여 안전하게 접근해볼 수 있게 한다.

double radius; // 부적절하게 접근 가능성이 있음
private double radius; // 부적절하게 접근 못하도록

단 여기서 생기는 문제가 하나 있다. 이전에 Circle이라는 새로운 객체를 선언한 다음 반지름은 내가 원하는 반지름의 값으로 설정해볼 수가 있었는데 이제는 객체 외부에서 접근할 수 없으므로 접근이 불가능해진다.

그렇다면 어떻게 접근할까? Access 메서드를 이용해서 접근을 해야한다. Access 메서드란 필요에 따라 특정 멤버 변수의 값을 얻어오거나 설정하는 메서드이다.

  • getter 지정된 멤버 변수의 값을 반환
  • setter 지정된 멤버 변수를 설정하는 메서드

메서드의 이름을 getter, setter로 짓는 것이 아니라 get, set 의 형태로 앞에 get과 set을 붙이자는 것이다.

public class Circle {
	
	static final double PI = 3.14159265;
	private double radius;
	
	void setRadius(double radius) {
		this.radius = radius;
	}
	
	double getRadius() {
		return radius;
	}
	
	double getArea() {
		return radius * radius * PI;
	}
	

}

6. 캡슐화와 정보은닉

6-2. 생성자


6-2-1. 생성자가 필요한 이유

여러 반지름을 가질 경우 set함수를 여러번 써야 할 수도 있다. 이런 반복 작업을 하기에는 번거럽다. 반복을 하는 대신 객체를 생성해주자마자 멤버 변수를 초기화를 시켜 동작을 줄일 수 있게 하는 것이 생성자이다.

public class CircleTest {
	public static void main(String[] args) {
		Circle c1 = new Circle();
		c1.setradius(1);

		Circle c5 = new Circle();
		c5.setradius(5);

		Circle c10 = new Circle();
		c10.setradius(10);
	}
}

6-2-2. 생성자

생성자란 프로그래머가 명시적으로 호출하는 것이 아니라 객체가 생성될 때 단 한번 자동으로 호출되어지는 메서드이다. 생성자는 객체가 생성할 때 멤버변수들을 적절하게 초기화를 시켜준다.
조건

  • 생성자 이름은 클래스 이름하고 같아야 한다.
  • 반환 자료형을 지정하지 않는다.(void를 쓰라는 의미가 아니라 아예 쓰지 말라는 소리)
  • 접근지정자와 매개변수 다 가질 수 있다. 보통 접근지정자는 클래스와 같은 접근지정자로 구현한다.
public class Circle {
	
	static final double PI = 3.14159265;
	private double radius;
	
    void setRadius(double radius) {
		this.radius = radius;
	}
	
	double getRadius() {
		return radius;
	}
	
	double getArea() {
		return radius * radius * PI;
	}
    
    Circle(double radius){
    	this.radius = radius;
    }
	

}

여기서 주의해야 할 점이 하나 있다.

public class CircleTest {
	public static void main(String[] args) {
		Circle c1 = new Circle(); //오류가 발생
		c1.setradius(1);
	}
}

프로그래머가 생성자를 정의를 한 순간 c = new Circle()와 같은 인자가 없는 객체를 만들고자 할 때 제공 되어지지 않는다. 생성자는 객체를 생성할 시에 멤버 변수를 초기화 시키기 때문에 인자 없는 객체를 생성하고자 할 때 오류가 난다. 그렇다면 명시적으로 인자가 없는 생성자를 정의해주면 된다. 이 개념과 관련된 생성자 오버로딩에 대해서 알아보자.

6-2-3. 생성자 오버로딩

매개변수 리스트가 다른 생성자들을 다중으로 정의하는 것은 생성자 오버로딩이라고 한다. 인자 없는 객체를 생성하기 위해 인자 없는 생성자를 만들어보자.

public class Circle {
	
	static final double PI = 3.14159265;
	private double radius;
	
    void setRadius(double radius) {
		this.radius = radius;
	}
	
	double getRadius() {
		return radius;
	}
	
	double getArea() {
		return radius * radius * PI;
	}
    
    Circle(double radius){
    	this.radius = radius;
    }
	
    Circle(){
    	this.radius = 1; //인수 없이도 반지름 값을 1로 초기화
    }

}

6-2-4. this();

위의 예시를 보면 생성자에 인자 있는 것을 한번, 없는 것을 한번 각자 초기화를 해줘야 하니 번거로울수도 있다.

this();를 이용하여 일반화된 생성자를 다른 생성자에 활용할 것이다.

public class Circle {
	
	static final double PI = 3.14159265;
	private double radius;
	
    void setRadius(double radius) {
		this.radius = radius;
	}
	
	double getRadius() {
		return radius;
	}
	
	double getArea() {
		return radius * radius * PI;
	}
    
    Circle(double radius){    //일반화된 생성자
    	this.radius = radius;
    }
	
    Circle(){
    	this(1);
    }

}

this(인수리스트);를 이용하면 간단하고 유지보수하기 쉬워진다.

6. 캡슐화와 정보은닉

6-2. 가비지 컬렉션

자바는 동적 할당된 메모리를 반납을 어떤 방식으로 할지 알아보자.


6-2-1. 가비지 컬렉션

JAVA는 소멸자를 가지고 있지 않다. 대신 JVM에 가비지 컬렉터(garbage collector)가 필요 없는 객체를 찾아 자동으로 제거해준다. 보통 참조 개수가 0인 영역을 제거한다.

0개의 댓글