Java Language
캡슐화
수색…
소개
꽤 중요한 변수를 가진 클래스가 있다고 가정하고 코드에서 다른 프로그래머가 설정 한 값을 받아 들일 수없는 값으로 설정했습니다. 코드가 코드에 오류를 가져 왔습니다. 솔루션으로, OOP에서 객체의 상태 (변수에 저장 됨)를 메소드를 통해서만 수정할 수 있습니다. 객체의 상태를 숨기고 객체 메소드를 통해 모든 상호 작용을 제공하는 것을 데이터 캡슐화라고합니다.
비고
변수를 private
로 표시하고 필요한 경우 public
변수를 숨기는 것보다 노출하는 것이 훨씬 쉽습니다.
캡슐화가 유용하지 않을 수도있는 한 가지 예외가 있습니다. "멍청한"데이터 구조 (변수를 보관하는 것이 유일한 목적의 클래스)입니다.
public class DumbData {
public String name;
public int timeStamp;
public int value;
}
이 경우, 클래스의 인터페이스는 데이터를 보유하고있다.
final
로 표시된 변수는 설정 후에 변경할 수 없으므로 캡슐화를 위반하지 않고 public
으로 표시 될 수 있습니다.
불변량을 유지하기위한 캡슐화
클래스에는 인터페이스와 구현의 두 부분이 있습니다.
인터페이스는 클래스의 노출 된 기능입니다. public 메소드와 변수는 인터페이스의 일부입니다.
구현은 클래스의 내부 작동입니다. 다른 클래스는 클래스 구현에 대해 알 필요가 없습니다.
캡슐화는 해당 클래스의 모든 사용자로부터 클래스의 구현을 숨기는 관행을 말합니다. 이것은 클래스가 내부 상태에 대한 가정을하도록합니다.
예를 들어, 각도를 나타내는이 클래스를 가져옵니다.
public class Angle {
private double angleInDegrees;
private double angleInRadians;
public static Angle angleFromDegrees(double degrees){
Angle a = new Angle();
a.angleInDegrees = degrees;
a.angleInRadians = Math.PI*degrees/180;
return a;
}
public static Angle angleFromRadians(double radians){
Angle a = new Angle();
a.angleInRadians = radians;
a.angleInDegrees = radians*180/Math.PI;
return a;
}
public double getDegrees(){
return angleInDegrees;
}
public double getRadians(){
return angleInRadians;
}
public void setDegrees(double degrees){
this.angleInDegrees = degrees;
this.angleInRadians = Math.PI*degrees/180;
}
public void setRadians(double radians){
this.angleInRadians = radians;
this.angleInDegrees = radians*180/Math.PI;
}
private Angle(){}
}
이 클래스는 기본 가정 (또는 불변성 )에 의존합니다. angleInDegrees와 angleInRadians은 항상 동기화 됩니다. 반원들이 공개 일 경우 두 각도 표현이 서로 연관되어 있다는 보장은 없다.
커플 링을 줄이기위한 캡슐화
캡슐화를 사용하면 클래스를 호출하는 코드에 영향을주지 않고 클래스를 내부적으로 변경할 수 있습니다. 이것은 커플 링 을 줄이거 나 주어진 클래스가 다른 클래스의 구현에 의존하는 정도를 줄입니다.
예를 들어, 앞의 예제에서 Angle 클래스의 구현을 변경해 보겠습니다.
public class Angle {
private double angleInDegrees;
public static Angle angleFromDegrees(double degrees){
Angle a = new Angle();
a.angleInDegrees = degrees;
return a;
}
public static Angle angleFromRadians(double radians){
Angle a = new Angle();
a.angleInDegrees = radians*180/Math.PI;
return a;
}
public double getDegrees(){
return angleInDegrees;
}
public double getRadians(){
return angleInDegrees*Math.PI / 180;
}
public void setDegrees(double degrees){
this.angleInDegrees = degrees;
}
public void setRadians(double radians){
this.angleInDegrees = radians*180/Math.PI;
}
private Angle(){}
}
이 클래스의 구현은, 각도의 1 표현만을 포함 해, 필요에 따라서 다른 각도를 계산하도록 (듯이) 변경되었습니다.
그러나 구현이 변경되었지만 인터페이스가 변경되지 않았습니다 . 호출 클래스가 angleInRadians 메서드에 액세스하는 데 의존하는 경우 새 버전의 Angle
을 사용하도록 호출 클래스를 변경해야합니다. 클래스를 호출하면 (자), 클래스의 내부 표현에 관해서는 안됩니다.