1. 데이터 은닉
- 데이터를 보호하기 위해서 사용(마음대로 변경 X)
- 변수는 private로 접근 막기
- getter, setter를 사용하여 변수 접근(public method)
class UnbelievableUserInfo {
// 데이터 은닉
private String name = "홍길동";
private int account = 10000;
public void setName(String name) {
// 데이터 보호
if (name != null) {
this.name = name;
} else {
System.out.println("잘못된 이름 입니다.");
}
}
public String getName() {
return this.name;
}
public void setAccount(int account) {
if (account >= 0) {
this.account = account;
} else {
System.out.println("값이 0보다 작습니다.");
}
}
public int getAccount() {
return this.account;
}
}
public class UnbelievableTest {
public static void main(String[] args) {
UnbelievableUserInfo info = new UnbelievableUserInfo();
System.out.printf("사용자 정보:%s, %d%n", info.getName(), info.getAccount());
info.setName(null);
info.setAccount( -1000);
System.out.printf("사용자 정보:%s, %d%n", info.getName(), info.getAccount());
}
}
2. 싱글톤 패턴
- 객체가 하나만 있는 경우 사용(굳이 여러개의 객체가 필요 없는 경우)
- 객체를 계속 생성/삭제 하는데 많은 비용이 들어서 재사용이 유리한 경우 사용
- 외부에서 생성자에 접근 금지 > 생성자의 접근 제한자를 private로 설정
- 내부에서는 private에 접근 가능하므로 직접 객체 생성 >> 멤버 변수이므로 private 설정
- 외부에서 private member에 접근 가능한 getter 생성 > setter는 불필요
- 객체 없이 외부에서 접근할 수 있도록 getter와 변수에 static 추가
- 외부에서는 언제나 getter를 통해서 객체를 참조하므로 하나의 객체 재사용
class SingletonClass {
// TODO:SingletonClass에 Singleton Design Pattern을 적용하시오.
private static SingletonClass instance = new SingletonClass();
private SingletonClass() {}
public static SingletonClass getInstance() {
return instance;
}
// END
public void sayHello() {
System.out.println("Hello");
}
}
public class SingletonTest {
public static void main(String[] args) {
// TODO:SingletonClass를 사용해보세요.
SingletonClass sc1 = SingletonClass.getInstance();
SingletonClass sc2 = SingletonClass.getInstance();
sc1.sayHello();
sc2.sayHello();
System.out.println(sc1 == sc2);
// END
}
}
3. 다형성(Polymorphism)
- 상속 관계에 있을 때 "조상 클래스의 타입"으로 "자식 클래스 객체를 레퍼런스" 할 수 있다.
public class PolyTest {
public static void main(String[] args) {
// 상속 관계 Object >> Person >> SpiderMan
SpiderMan sman = new SpiderMan;
Person p = samn;
Object o = sman;
}
}
4. 다형성의 활용
- 다른 타입의 객체를 다루는 배열
public class PolyTest {
public static void main(String[] args) {
Person[] persons = new Person[10];
person[0] = new Person();
// Person 클래스는 SpiderMan클래스의 조상클래스이므로 가능
person[1] = new SpiderMan();
}
}
- 매개변수의 다형성
// 모든 객체를 호출할 수 있도록 한다.
public void println(Object x) {
String s = String.valueOf(x);
if (getClass() == PrintStream.class) {
// need to apply String.valueOf again since first invocation
// might return null
writeln(String.valueOf(s));
} else {
synchronized (this) {
print(s);
newLine();
}
}
}
※ 조상을 파라미터로 처리한다면 객체의 타입에 따라 메서드를 만들 필요가 없어진다.
5. 객체의 형 변환
- 메모리에 있는 것과 사용할 수 있는 것의 차이
- person은 person의 기능만을 알고 있고 SpiderMan의 기능은 알지 못한다.
Person person = new SpiderMan(); // 메모리에는 SpiderMan() 객체를 저장
- 묵시적 형 변환
※ 하위 타입을 상위 타입으로 변환
Phone phone = new Phone();
Object obj = phone;
- 명시적 형 변환
※ 상위 타입을 하위 타입으로 변환
Phone phone = new SmartPhone();
SmartPhone sPhone = (SmartPhone)phone;
- 참조형 객체의 형 변환
※ 메모리의 객체는 fireWeb이 없음 >> 컴파일 시 오류 발생
Person person = new Person();
SpiderMan sman = (SpiderMan) person;
sman.fire();
- instanceof 연산자 : 실제 메모리에 있는 객체가 특정 클래스 타입인지 boolean으로 리턴
Person person = new Person();
if (person instanceof SpiderMan) {
SpiderMan sman = (SpiderMan) person;
}
6. 참조 변수의 레벨에 따른 객체의 멤버 연결
- 타입에 따라 연결이 다르다. (부모 타입이면 부모에서 찾고 자식이면 자식에서 찾는다.)
- 하지만 오버라이딩된 메서드(변수 X)가 있다면 부모에서 찾다가 자식메서드(메모리 최하위)로 바인딩 된다.
7. 정적 바인딩
- 컴파일 단계에서 참조 변수의 타입에 따라 연결이 달라짐
- 상속 관계에서 객체의 멤버 변수가 중복될 때 또는 static method
- 속도 빠름, 메모리 효율 높음
8. 동적 바인딩
- 다형성을 이용해서 메서드 호출이 발생할 때 runtime에 메모리의 실제 객체의 타입으로 결정
- 상속 관계에서 객체의 instance method가 재정의 되었을 때 마지막에 재정의 된 자식 클래스의 메서드가 호출됨.
- 속도 느림, 메모리 효율 낮음, 다형성 좋음
'Web > JAVA' 카테고리의 다른 글
예외 처리(exception handling) (0) | 2024.01.22 |
---|---|
abstract class, Interface, generic (0) | 2024.01.19 |
상속(Inheritance), overriding, package, import, 제한자 (0) | 2024.01.17 |
클래스, 객체, 메서드, 변수, 생성자 (0) | 2024.01.16 |
기본 문법, 배열 (0) | 2024.01.15 |