본문 바로가기
Web/JAVA

데이터 은닉(Encapsulation), 다형성(Polymorphism), Singleton

by 당진개발자 2024. 1. 18.

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가 재정의 되었을 때 마지막에 재정의 된 자식 클래스의 메서드가 호출됨.

- 속도 느림, 메모리 효율 낮음, 다형성 좋음