-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Labels
🐸 04 Classes & Interfaces4장 클래스와 인터페이스4장 클래스와 인터페이스
Description
Chapter : 4. 클래스와 인터페이스
Item : 16. public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라
Assignee : Lainlnya
🍑 서론
🍑 본론
캡슐화의 이점을 제공하지 못하는 예시
- API를 수정하지 않고는 내부 표현을 변경할 수 없다.
- 불변식을 보장할 수 없으며, 외부에서 필드에 접근할 때 부수 작업을 수행할 수도 없다.
class Point {
public double x;
public double y;
}캡슐화된 예시
✅ 패키지 바깥에서 접근할 수 있는 클래스라면 접근자를 제공하면, 유연성을 높일 수 있다.
class Point {
private double x;
private double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() { return x; }
public double getY() { return y; }
public void setX(double x) { this.x = x; }
public void setY(double y) { this.y = y; }
}package-private 클래스 혹은 private 중첩 클래스라면 데이터 필드를 노출하는 것이 문제가 되지 않는다.
✅ package-private 클래스
com.example.myapp 패키지 외부에서는 접근할 수 없으므로 데이터 필드를 노출해도 큰 문제가 없다.
package com.example.myapp;
// 패키지 내부에서만 접근 가능한 클래스
class PackagePrivateClass {
int data; // 데이터 필드를 노출
}✅ private 중첩 클래스
내부에서만 사용할 수 있고, private 클래스는 외부에서 접근할 수 없다. 따라서 데이터 필드를 노출하는 것이 문제가 되지 않는다.
public class OuterClass {
// 외부에서 접근할 수 있는 public 메서드
public void doSomething() {
NestedPrivateClass nested = new NestedPrivateClass();
nested.setData(42); // 중첩 클래스의 데이터 필드에 접근
System.out.println(nested.getData()); // 중첩 클래스의 데이터 필드 출력
}
// private 중첩 클래스
private static class NestedPrivateClass {
private int data; // 데이터 필드를 노출
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
}
}java에서 public 클래스 필드를 직접 노출하지 말라는 규칙을 어긴 사례
Dimension의 경우 내부를 노출해서 아직까지 성능 문제를 해결하지 못했다.
public class Dimension extends Dimension2D implements java.io.Serializable {
/**
* The width dimension; negative values can be used.
*
* @serial
* @see #getSize
* @see #setSize
* @since 1.0
*/
public int width;
/**
* The height dimension; negative values can be used.
*
* @serial
* @see #getSize
* @see #setSize
* @since 1.0
*/
public int height;
public double getWidth() {
return width;
}
/**
* {@inheritDoc}
* @since 1.2
*/
public double getHeight() {
return height;
}
/**
* Sets the size of this {@code Dimension} object to
* the specified width and height in double precision.
* Note that if {@code width} or {@code height}
* are larger than {@code Integer.MAX_VALUE}, they will
* be reset to {@code Integer.MAX_VALUE}.
*
* @param width the new width for the {@code Dimension} object
* @param height the new height for the {@code Dimension} object
* @since 1.2
*/
public void setSize(double width, double height) {
this.width = (int) Math.ceil(width);
this.height = (int) Math.ceil(height);
}
}public 클래스의 필드가 불변이라면
- 불변식을 보장하기 때문에 직접 노출할 때의 단점이 줄어든다.
- API를 변경하지 않고는 표현 방식을 바꿀 수 없고, 필드를 읽을 때 부수 작업을 수행할 수 없는 것은 여전히 단점이다.
public final class Time {
private static final int HOURS_PER_DAY = 24;
private static final int MINUTES_PER_HOUR = 60;
public final int hour;
public final int minute;
}🍑 결론
✅ public 클래스는 절대 가변 필드를 직접 노출해서는 안된다. => 불변 필드면 노출해도 덜 위험하지만 권장X
✅ package-private 클래스나 private 중첩 클래스에서는 종종 필드를 노출하는 것이 나을 때도 있다.
Referenced by
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
🐸 04 Classes & Interfaces4장 클래스와 인터페이스4장 클래스와 인터페이스