1. 캡슐화(정보은닉)
접근/수정 등의 권한을 줄 필요가 있을 때 Enum 생성으로 권한 필드/생성자 추가해준 후 if문을 통해 부여
public String getSudoUserPw(User user) {
if(authorization == Authorization.ADMIN || authorization == Authorization.DEV) {
return user.userPw;
} else {
System.out.println("[ERROR] Check Your Authorization!");
}
return null;
}
public void setSudoUserPw(User user, String userPw) {
if(authorization == Authorization.ADMIN || authorization == Authorization.DEV) {
user.setUserPw(userPw);
} else {
System.out.println("[ERROR] Check Your Authorization!");
}
}
2. hashCode() / equals()
//자바의정석 내용 참고
public class object {
...
public native int hashCode();
//native = OS
👉 equals()를 오버라이딩하면 equals()의 결과가 true인 두 객체의 hashCode도 같아야 하기 때문에 hashCode()도 오버라이딩 해주어야한다.
(Q. 재정의되어 같아진 hashCode 말고 객체마다 다른 hashCode값 필요할 때는?
A. identityHashCode()를 사용해주면 오버라이딩 전의 각자 다른 hashCode 값이 출력된다.)
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && studentId.equals(student.studentId) && name.equals(student.name);
}
public static int hashCode(byte[] value) {
int h = 0;
int length = value.length >> 1;
for (int i = 0; i < length; i++) {
h = 31 * h + getChar(value, i);
}
return h;
}
❓ 31을 곱해주는 이유
bit shift(<<)연산을 사용할 수 있다.
ex) 임의의 수 num에 2의 n승을 곱한 것 = num << n
32는 2^5으로 num << 5 인데
31은 32-1이므로 JVM에서는 31 * num = num << 5 - num 이 되어 곱하기 연산보다 비트를 한칸 옮기는 최적화 된 연산이 가능
짝수를 사용하면 위와 같은 shift 연산 시 overflow가 발생할 수 있고 그렇게되면 오른쪽이 모두 0으로 차게되어 정보의 손실이 일어날 수 있어서 홀수 사용
소수여야하는 이유는 그닥 없음
3. 싱글톤 패턴(Singleton Pattern)
싱글톤의 정의 : 자주 사용하는 클래스 기능의 경우, 메모리에 객체를 생성하여 사용하면 비효율적이기 때문에 클래스의 객체를 미리 메모리에 생성해놓고 사용하는 것. 따라서 한개의 객체만 메모리에 존재하게 한다.
전체 프로그램에서 단 1개의 인스턴스만 생성되게하여 생성된 인스턴스는 getInstance()를 통해 접근한다.
인스턴스를 생성할 클래스의 생성자와 변수는 private으로 선언하고 인스턴스에 접근할 메서드는 public으로 선언한다.
외부 클래스에서 new를 통한 인스턴스 생성은 불가하다.
public class Electronics {
private static Electronics electronics;
//private static 인스턴스 변수
public static Electronics getInstance() {
if(electronics == null) {
electronics = new Electronics();
}
return electronics;
}
// public static getInstance() method 구현
// 처음 null값이라면 new로 생성
private Electronics() {}
// private 생성자
이렇게 싱글톤으로 작성해주면
public class Main {
public static void main(String[] args) {
Electronics electronic1 = Electronics.getInstance();
Electronics electronic2 = Electronics.getInstance();
System.out.println(electronic1);
System.out.println(electronic2);
}
}
main에서 두개의 객체를 getInstance()로 생성 한 다음 주소를 출력했을 때 주소값이 동일함을 알 수 있다.
즉 같은 인스턴스를 가리키고 있음을 알 수 있다.