본문 바로가기
JAVA Basic

공부 12일차) 타입변환과 다형성~

by 넴넴L 2023. 1. 11.
728x90

안녕하세요 넴넴입니다.

자바 기초가 생각보다 얼마 남지 않았네요 한 15일 이내로 끝이 날 거 같습니다.

화이팅 하자고요!

 

다형성이란?
- 같은 타입이지만 실핼 결과가 다향한 객체 대입 가능한 성질
(부모타입에는 모든 자식 객체가 대입 가능)
자동 타입 변환
- 프로그램 실행 도중 자동 타입 변환이 일어나는 것
- 바로 위의 부모가 아니더라도 상속 계츠으이 상위면 자동 타입 변환 가능
(부모클래스 타입의 변수에 자식클래스 타입의 객체 대입가능)
(변환 후에는 부모 클래스 멤버만 접근 가능)

코드로 이해하러 갑시다

 

일단 총 5개 class를 만듭시다

그리고 위 사진처럼 B와 C는 extends A로

D는 extends B, E를 extends C로 해주고

이대로 코드를 추가 해줍시다.

아래 빨간 줄이 생긴 것은 B는 E의 부모 클래스 타입이 아니기 때문이고

C는 D의 부모 클래스 타입이 아니라서 그렇습니다.

이런 형식이죠

필드의 다형성
- 다형성을 구현하는 기술적 방법
(부모 타입으로 자동 변환, 재정의된 메소드(오버라이딩))

class를 3개 만들어서

Parent Class
Child Class

위에 @Override는 무조건 적어줘야합니다.(오버라이딩)

ChildEx Class

최하단 것은 오류가 나는게 정상입니다.

오류 코드를 주석처리하고 출력을 해보면

다형성은 부모클래스 타입의 변수에 자식클래스 타입의 객체를 대입해 부모클래스 타입의 객체를 생성한 것처럼 사용.

무슨 소리냐면 Parent parent = child; 라는 게 뭔가 이상해 보입니다.

이때까지 만들 때 생각해보면 저렇게 만들면 안되거든요.

 

중요

이것은 Parent 클래스 타입의 변수 parent에 자식 클래스인 child의 객체 대입을 한 것입니다.

부모 클래스 타입의 변수에 저장된 내용이 자식 클래스 타입의 객체이므로 실제 데이터는
자식 클래스 타입의 객체인 child입니다. 따라서 출력되는 내용도 child 멤버가 출력이 됩니다.

 

그런데 method3()이 실행이 되지가 않습니다.

왜냐하면 Parent 클래스 타입의 변수 parent에 저장된 내용이 자식 클래스 타입의 객체인 child라고 하더라도
Parent 클래스 타입의 변수이기 때문에 사용할 수 있는 멤버는 Parent클래스의 멤버 밖에 사용할 수 없기 때문입니다.

 

다형성 2번째 예제

클래스 생성 후 코드 추가해주세요 총 5개 입니다.(길어요!)

Tire Class
Car Class
HankookTire Class
KumhoTire Class
CarEx Class

천천히 코드를 읽어보시면 어디에서 어디로 가는지 보입니다.

(귀찮아서 설명은 하지 않는게 아니라 정말로 보입니다.)

이제 이 코드를 조금 바꿔서 배열로 표현해봅시다. 

 

Car Class
CarEx Class

Car, CarEx 코드만 변경해주었는데 짧게 설명하자면

problemLocation이 0이 아니면 계속 실행됩니다(for문 사용해서)

지금은 i <= 5라서 총 5번을 실행했고 펑크가 나면 다음 실행 시 수명을 15로 설정을 해놔서

~~~ 수명 : 14회로 나온 것을 볼 수 있습니다.(배열은 0부터 시작해서 0~14까지 실행된다.)

 

매개변수의 다형성
- 매개변수가 클래스 타입일 경우
(해당 클래스의 객체 대입이 원칙이나 자식 객체 대입하는 것도 허용)

class 5개를 새로 만들어 줍시다.

Vehicle Class
Bus Class
Taxi Class
Driver Class
DriverEx Class

다형성이 없을 경우에는

Bus bus = new Bus();

bus.run();

이런 문구로 실행을 했지만

 

다형성을 사용함으로써

Vehicle vehicle = new Vehicle();

vehicle.run();

으로 선언을 해서 아래 처럼

vehicle = bus;

vehicle.run();

처럼 사용할 수 있게 됩니다.

이것을 위에서 설명했듯이 규격화라고 합니다.

부모 타입에 모든 자식 객체가 대입이 될 수 있고 사용하는 방법을 고정시켜 줍니다.

 

이렇게 출력해도 답은 똑같이 나온다.

 

강제 코드 변환

1. 부모 타입을 자식 타입으로 변환화는 것
객체의 원본이 자식클래스의 객체다.
원본이 부모클래스의 객체이면 자식클래스 타입으로 변환 불가

2. 조건
자식 타입을 부모 타입으로 자동 변환 후, 다시 자식 타입으로 변환할 때

3. 강제타입변환이 필요한 경우
자식 타입이 부모 타입으로 자동 변환(부모 타입에 선언된 필드와 메소드만 사용 가능)

코드를 써보며 이해해봅시다.

class를 총 3개 만들어줍시다.

Parent Class
ChildClass
ChildEx Class

이건 당연하게 값이 이렇게 나오는 것을 알 수 있을것입니다.

부모 클래스인 Parent클래스 타입의 변수 Parent에 자식 클래스인 Child 클래스의 객체 child를 대입합니다.

 

이 코드는 왜 안될까요?

접근할 수 없습니다. 자식 클래스 타입의 객체를 부모 클래스 타입의 변수에 대입하면
부모 클래스의 멤버에만 접근이 가능합니다.

 

이것이 강제 형 변환입니다.

 

객체 타입 확인
1. 부모 타입이면 모두 자식 타입으로 강제 타입 변환할 수 있는 것이 아닙니다.
방금 썼던 Child child2 = (Child) parent; 는 강제 타입 변환을 할 수 없습니다.

2. 그래서 먼저 자식 타입인지 확인 후 강제 타입을 실행해야 합니다.
- instanceof를 사용.

3개의 클래스를 또 만들어 줍시다.

Parent2 Class
Child2 Class
InstanceOfEx Class

instanceof는 연산자입니다. 앞에 있는 객체가 뒤에 있는 것과 동일한지 확인해주는 것입니다.

이 코드를 추가해서 실행해주면 에러가 뜹니다.

위에서 선언해서 받아왔었던 parentB 객체를 method2 에 있는 parent에 매개변수로 받아와 강제타입변환을 하면

오류가 발생합니다.

 

왜냐하면

원래는 다형성에서 강제 타입 변환은 원본이 자식클래스이지만 잠시 부모로 변경하고 다시 자식으로 변경하지만

원본이 부모클래스이면 자식 클래스로 변경을 할 수 없기 때문입니다.

method2를 주석처리하고 method1로 바꿔주면 실행이 됩니다.

instanceof가 지정한 객체가 원래 무슨 타입인지 확인을 해줍니다.

앞 parent 타입과 뒤 Child 타입이 같은지 true/false로 값을 매겨줍니다.

parentB는 Parent() 원본이 부모 클래스이므로

지금은 false이므로 변환되지 않음으로 뜹니다.

 

이렇게 쓰는 이유는 안전한 프로그래밍을 위해 사용합니다.(한번 더 검사하고 쓰라고~)

 

오늘도 길었는데 고생하셨어요. 위에서 말했듯이 15일 이내에 기초는 끝이 날거 같네요 그때까지

힘내보자구요!