728x90

이 강의는 자바의 프로젝트를 어떻게 만드는지, 또한 빌드를 어떻게 하는지에 대한 강의를 진행하지 않는다.

그러나 자바의 기본적인, 그리고 자바에 필수적인 기능들도 분명 존재하고 이 블로그엔 그 작업에 필요한 포스팅도 함께 제공하고 있다.

그 정보를 확인하고 싶다면 여기를 참조하라. 양이 조금 되고 현재진행형으로 늘어나고 있으므로 페이지내의 찾기(ctrl+f 나 cmd+f)로 찾아보도록하자.


과거에 캐스트 연산자가 있다고 한적이 있다.

캐스트 연산자는 특정 자료형을 다른 자료형으로 변환하는 연잔자이다.

예를 들어보자. int형이란 자료형과 float형이란 자료형은 저장하는 방식이 다르다.

더 나아가서 int형과 long형역시 저장하는 방식이 조금 다르다고 할 수 있다.

따라서 특정 자료형을 다른 자료형과 호환되게 변경하는 방법을 타입 캐스팅, 한국말로 형변환이라고 한다.


프리미티브타입들의 타입캐스팅은 모두 서로 변환 가능하다. 따라서 문제가 생길건 없다.

데이터의 손실은 조금 있을지 몰라도 타입캐스팅이 실패하는 경우는 없다.

프리미티브타입의 타입캐스팅은 모두 동등 타입캐스팅이다.


클래스타입들은 조금 다르다.

클래스타입들은 기본적으로 타입캐스팅이 불가능하다.

잘 생각보면 쉽게 이해할 수 있다. 여러 자료형이 묶어져 있는 클래스 타입이 서로 호환될리가 만무하다.

그러나 자바 18강 다형성을 봤다면 클래스타입도 타입캐스팅이 된다는걸 알 수 있다.

단 타입 캐스팅이 되는 조건은 조금 까다롭다. 바로 상속관계여야한다.


상속관계의 타입캐스팅은 프리미티브타입들의 타입캐스팅과는 성격이 다르다.

프리미티브타입들의 타입 캐스팅은 동등한 타입캐스팅이지만 상속관계는 상하관계가 존재한다.

이를 말하자면 아래와 같다.


클래스의 타입캐스팅(형변환)


1.부모클래스는 명시적인 타입캐스팅 없이 자식과 연결 할 수 있다. 이를 업캐스팅(Up-Casting)이라 한다.

2.자식클래스는 명시적인 타입캐스팅이 있다면 부모와 연결 할 수 있다. 이를 다운캐스팅(Down-Casting)이라 한다.

3.상속관계가 아니면 타입캐스팅은 불가능하다.


전시간의 예제를 보자.


public class Main {
public static void main(String[] args) {
Shape r = new Rectangle(0, 0, 10, 20);
Shape c = new Circle(0, 0, 9, 9);
System.out.println(r.getArea());
System.out.println(c.getArea());
}
}


Rectangle클래스는 Shape를 상속받았다.

다형성에 의해서 Shape=Rectangle라는 코드가 가능하다.

그러나 정확하게 말하면 이 둘의 연결은 이런 개념이 아니다.


자바에서는 왼쪽과 오른쪽을 무조건 동등하게 맞춰야한다.

이걸 항상 인식해야한다. 왼쪽 변수와 오른쪽 변수는 동등해야한다.

이는 기본타입이건 프리미티브타입이건 똑같다.


예를 들어보자.

int a=5;

float f = a;

이런 코드는 아무 에러가 뜨지 않는다. 사실 위의 코드는 암묵적으로 아래와 같은 형식이 된다.

float f = (float)a;

우리가 코드를 입력하지 않아도 자동으로 타입캐스팅이된다.


클래스 관계에서는 두가지의 상황이 있다고 했다.

부모클래스가 자식과 연결되는 업캐스팅, 그리고 자식클래스가 부모와 연결되는 다운캐스팅이 있다고했다.

Rectangle은 Shape의 모든 것을 가지고 있다. 따라서 Shape=Rectangle이라는 코드가 가능하다.

이는 암묵적으로 Shape=(Shape)Rectangle이라는 코드가 된다.


그러나 반대의 경우는 조금 다르다.

예를들어 전의 코드를 조금만 바꿔서 다시 실행해 보도록하자.


public class Main {
public static void main(String[] args) {
Shape r = new Rectangle(0, 0, 10, 20);
Circle c = new Shape(0, 0, 9, 9);
System.out.println(r.getArea());
System.out.println(c.getArea());
}
}


이 경우는 실행이 될까?

Circle클래스는 Shape를 상속받았다. 이 경우에 실행이 안된다. 그 이유는 Circle=Shape 구문은 다운캐스팅이다.

따라서 다운캐스팅은 명시적으로 해야만한다.


public class Main {
public static void main(String[] args) {
Shape r = new Rectangle(0, 0, 10, 20);
Circle c = (Circle) new Shape(0, 0, 9, 9);
System.out.println(r.getArea());
System.out.println(c.getArea());
}
}


이 겨우 이제 에러는 나지 않는다. 이렇게 명시적으로 캐스팅해주면 된다.

정작 실행해보면 에러가 뜨는 것을 알 수 있다. 그 이유는 Circle에 연결된게 원래는 Shape이기 때문이다.

왜냐하면 Circle이  Shape보다 범위가 더 넓기 때문이다.

Shape가 아무래도 부모클래스이다보니 Circle의 클래스가 더 범위가 넓고 메소드가 다를 수 있기 때문이다.

그래서 Circle에 연결되는애도 원래는 Circle이여야 가능하다.


public class Main {
public static void main(String[] args) {
Shape r = new Rectangle(0, 0, 10, 20);
Shape sc = new Circle(0, 0, 9, 9);
Circle c = (Circle) sc;
System.out.println(r.getArea());
System.out.println(c.getArea());
}
}


여기서 보면 sc는 원래는 Circle이다. 따라서 이렇게 짜면 이제는 제대로 실행됨을 확인할 수 있다.

+ Recent posts