캡슐화와 다형성

방혁·2024년 1월 21일

Java

목록 보기
4/4

Encapsulation (캡슐화)

데이터 은닉과 보호

데이터 은닉

  • public으로 선언된 것들을 private접근으로 막자
  • 공개되는 메서드를 통한 접근 통로 마련
    -setter / getter

데이터 보호

  • setter / getter메소드 내부에서 데이터 보호에 대한 로직 작성

디자인패턴

  • 어떠한 목적을 달성하기 위해 사람들의 경험에서 나온 패턴

Singleton 디자인패턴

  • 객체의 생성을 제한해야하는 경우
    1. 여러개의 객체가 필요 없는 경우
    - stateless객체 : 객체를 구별할 필요가 없는 경우, 기능만 있는경우
    1. 객체를 계속 생성/삭제하는데 많은 비용이 들어서 재사용이 유리한 경우
  • 만드는 방법
    1. 외부에서 생성자 접근 금지 - 생성자의 접근 제한자를 private
    1. 내부에서는 private에 접근 가능하므로 직접 객체 생성 - 멤버변수 private
    2. 외부에서 private member에 접근 가능한 getter생성
    3. 객체 생성없이 접근가능하도록 static추가

Polymorphism(다형성)

다형성

  • 하나의 객체가 많은 형(타입)을 가질 수 있는 성질
  • 상속관계에서 조상 클래스의 타입으로 자식 클래스 객체를 레퍼런스 가능
  • Object는 모든 클래스의 조상 -> Object의 배열은 어떤 타입의 객체라도 다 저장할 수 있음
  • 기본형은 Object를 상속 받지 않았음
    -auto boxing으로 Wrapper클래스를 통해 저장됨
  • API에서 파라미터로 Object를 받는다는 것을 모든 타입을 다 파라미터로 받을 수 있음 !

객체의 형 변환

메모리에 있더라도 참조하는 변수의 타입에 따라 접근할 수 있는 내용이 제한.
자식을 부모타입으로 받으면 자식의 기능이 메모리에 있지만 사용할 수 없다.

  • 사용할려면 명시적 캐스팅을 통해 상위타입을 하위타입으로 형 변환 후 사용 !
    참고) 하위 타입을 상위타입으로 형변환할 때는 묵시적 캐스팅이 일어남

상위 타입을 하위타입으로 형 변환할 시

  • 무작정 자손으로 바꿀 수는 없다.
    -실행 시 오류 발생. 컴파일시 확인 불가
  • instanceof연산자를 사용하여 변경가능한 지 확인

참조 변수의 레벨에 따른 객체의 멤버 연결

class SuperClass {
    String x = "super";
    public void method() {
        System.out.println("super class method");
    }
}

class SubClass extends SuperClass {
    String x = "sub";
    @Override
    public void method() {
        System.out.println("sub class method");
    }
}

public static void main(String[] args) {
	SubClass subClass = new SubClass();
	System.out.println(subClass.x);
    subClass.method();
    
    SuperClass superClass = subClass;
    System.out.println(superClass.x);
    superClass.method();
}

위 코드의 결과는 ?
sub
sub class method
super
sub class method

정적바인딩

  • 컴파일 단계에서 참조 변수의 타입에 따라 연결이 달라짐
  • 상속 관계에서 객체의 멤버변수(static/instance)가 중복될 때 또는 static method

동적바인딩

  • 다형성을 이용해서 메서드 호출이 발생할 때 runtime에 메모리의 실제 객체의 타입으로 결정
  • 상속 관계에서 객체의 instance method가 재정의(오버라이드)되었을 때 마지막에 재정의 된 자식 클래스의 메서드가 호출됨

println()은 toString()이 출력됨. 따라서 자식 클래스에서 재정의해서 사용.

상위 타입으로 올라갈 수록 활용도가 높아지지만 복잡성이 증가 !
따라서 많은 경우 비즈니스 로직 상 최상위 객체를 사용하는 것이 좋다.

몇가지 메서드재정의

toString()

  • 객체를 문자열로 변경하는 매서드
public String toString() {
	return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
  • 주소값이 반환되므로 클래스에서 재정의해서 사용.

equals()

  • 두 객체가 같은지를 비교하는 메서드
  • 원래는 주소값 비교 (==)
  • 따라서 equals를 내용비교로 재정의.

hashCode()

  • 객체의 해시 코드 : 시스템에서 객체를 구별하기 위한 값
  • equals 매서드를 재정의할 때는 반드시 hashCode도 함께 재정의
profile
반갑습니다 👋

0개의 댓글