사전에서 다형성이란 다음과 같이 정의 되어 있다.
자바에서 다형성은 변수를 통해서 여러 객체를 참조 할 수 있도록 한 것을 말한다.
처음에 잘 이해가 안 갈 수 있다. 열심히 공부 해보자!
이 내용은 책이나 유튜브, 구글 검색 등을 통해서 많이 알 내용이니 간단하게 넘어가자.
1, 2번이야 그렇다고 쳐도 3번은 왜 명시해야 하는지 이유를 생각해 봤다.
예시로 보자
ChildClass child1 = new ChildClass();
ChildChildClass ccClass = new ChildChildClass(); // child class 의 child
ParentClass parent = child1; // 암묵적 형변환
ChildClass child2 = (ChildClass)parent; // 명시적 형변환
ChildClass child3 = ccClass; // 암묵적 형변환
다음과 같이 Child Class 에서 또 자식 객체를 만들었을 경우를 보자
위와 같이 일어나게 되는데
아래와 같을 경우 자손이 부모로 바뀌는지 부모가 자손으로 바뀌는지 확실하게 알 수 없을 뿐더러
( 뇌피셜 ) 자식은 추가 확장 내용 ( Instance 변수 ) 를 버리면 부모가 될 수 있지만
부모는 추가 데이터를 받아오지 않으면 쓰레기 값이 들어오기 때문에 명시적으로 바꿔야 한다고 생각 된다.
결론
아마 명확하게 업 캐스팅과 다운 캐스팅을 구분 짓기 위해서 나눈 목적이 아닐 까 생각 된다.
캐스팅이 가능한 지 여부를 boolean
타입으로 확인하는 연산자
reference_value_name instanceof 'className'
이전 포스팅에서는 equals 함수 Override 를 할 때 .getClass() 함수를 사용 했었는데
실무에서는 instanceof 연산자를 상당히 많이 쓴다. 확장성에 상당히 열려 있고
getClass 는 그 클래스에 해당하는 값만 가져오기에 상속 하여 캐스팅이 가능 하더라도
equals 내부에서 사용 할 경우 상속 받는 친구들은 사용이 불가능 하다. ㅜ.ㅜ
추상 클래스도 있지만 사실 실무에서 아주 많이 사용 하는 건 인터페이스고 추상 클래스 사용 빈도도 상당히 적고 어려운 내용이 아니기에 간단하게 집고 넘어 가도록 하겠다.
인터페이스의 기본 구조
class
키워드 대신 interface
키워드를 사용접근제어자 interface 인터페이스이름 {
public static final 타입 상수이름 = 값;
final int 변수 = 2; // public static 생략
static int 변수2 = 3; // public & final 생략
...
public abstract 메소드이름(매개변수목록);
void 메소드이름2() //public abstract 생략
...
}
public static final
로 선언public abstract
로 메소드 정의인터페이스의 제약 조건
인터페이스의 다중 implement
이런 경우에 인터페이스를 사용하지 않는다면 이런 Query Class ( 이제 Repo Class 라고 하겠다) 를 의존하는 모든 클래스에 객체를 모두 바꿔 주어야 한다. 변경 가능성에 상당히 닫혀있는 상태라고 할 수 있다.
어디서 사용하는지도 잘 모르겠고 바꾸기도 귀찮은데 Repo Class 내부 함수 쿼리나 바꿔야지 할 수 있다. 이런 경우 상당히 확장 가능성에 닫혀있는 상태라고 할 수 있다. 만약 데이터 베이스를 옮겼는데 또 다시 이런 일이 생긴다면 ? 또 전체 코드를 갈아 엎어야 하는 상태가 올 수 있다.
이를 인터페이스를 통해 간단하게 해결이 가능하다. 모든 의존하는 클래스들을 인터페이스 타입으로 받게 하여 인터페이스를 상속 받는 Impl class 로 만들게 되면 DI 를 하는 class 만 바꿔주면 된다.
@Bean
public InterfaceDI DI(InterfaceDI interfaceDI){
this.InterfaceDI = interfaceDI;
}
//extenal
void main(){
DI(**new InterfaceDIImpl()**);
// 위 부분만 바꿔주면 됨
}