[JAVA] 타입변환 (Up || Down Casting)

강민승·2023년 8월 31일
0

JAVA

목록 보기
6/15

📌 Casting

캐스팅은 OOP의 다형성과 관련이 있다.
자바에서의 데이터형은 크게 2가지로 [기본형, 참조형] 이 있다.

  • 기본형 : boolean, int, short, byte,double, long, float, char
  • 참조형 : 만들기 나름!

캐스팅의 목적은 단순히 데이터를 바꾸기 위한 목적이 아닌 코드를 작성하는 프로그래머가 데이터 정보에 대한 이해를 바탕으로 OOP의 다형성 측면에서 사용한다.

예를들어,

int a = 1.0;

이렇다면 컴파일 에러가 뜬다.
변수는 분명 int 정보만을 원하고 있고 1.0이라는 실제 데이터는 int 정보를 이미 가지고 있고, 소숫점을 표현하는 double 데이터다.

그럼? 변수 a가 원하는 정보가 실제 데이터에 있는데 왜 에러가 발생할까?

-> 은, 데이터의 손실을 막기 위함이다. 실제로 데이터가 손실되는 것을 알고 OOP의 다형성을 이용하고 싶다면

int a = (int) 1.0;

라고 쓰면 된다.

이러한 개념 중 UpCastig과 DownCasting이 있다.

📍 UpCasting

Java에서, 서브 클래스는 해당하는 수퍼 클래스의 모든 특성을 상속받는다. 때문에 서브 클래스는 수퍼 클래스로 취급될 수 있다.

ex) 수퍼 클래스 : 은하계, 서브 클래스 : 지구일 때 
**지구는 은하계 중 일부이다.** 라고 할 수 있다.

즉, UpCasting이란 서브 클래스의 객체가 수퍼 클래스 타입으로 형변환 되는 것을 말한다.

Code

package study.test.java;


class Person{
	String name;

	public Person(String name) {
		this.name = name;
	}
}

class Student extends Person{
	
	String age;
	
	public Student(String name) {
		super(name); // super 키워드에 대해서는 따로 설명하겠다.
	}
}
public class CastingTest {
	public static void main(String[] args) {
    
    	// student 참조변수를 이용하면 age, name에 접근 가능하다.
    	Student student = new Student("도리도리"); 
	
    	// person 참조변수를 이용하면 Student 객체의 멤버 중에서 Person 클래스의 멤버에만 접근이 가능하다.
	Person person = student; // "업 캐스팅"
    
	person.name = "세진세진";
	person.age = "24"; // 컴파일 오류 ~!
	
	}
}

위의 코드에서 , person 참조변수는 Student 객체를 가리킨다.
하지만 Person 타입이므로 자신의 클래스에 속한 멤버만 접근 가능하다.
(컴파일 시점에서 오류가 남)
person.age를 했을 때 컴파일 오류가 나는것이 바로 그 예시이다.

이와 같이 업 캐스팅을 하게 되면 객체(여기서는 Student 객체를 말함) 내의 모든 멤버에 접근할 수 없다. 멤버 필드 뿐 아니라 메서드도 마찬가지 이다.

또한, 명시적인 타입 캐스팅 선언을 하지 않아도 된다.
서브 클래스인 Student는 Person 타입 이기도 하기 때문이다.
무슨 말인지 잘 모르겠다면 아래의 코드를 참고하자.

Student student = new Student();
Person person = (Person) student; // 이렇게 앞에 (Person) 붙여주는거 안해도 된다는 것.

📍 DownCasting

DownCasting은 반대로 수퍼 클래스의 객체를 서브 클래스 타입으로 형변환 하는 것을 의미한다. 이러한 캐스팅은 명시적으로 수행해야 한다. 이는 프로그래머가 명확하게 어떤 객체의 타입을 다른 타입으로 변환하려는 의도를 가지고 있다는 것을 보여주기 위해서다.

DownCasting을 할 때에는, 실제로 참조하고 있는 객체의 타입이 DownCasting의 타겟 타입이어야 한다. 그렇지 않으면 실행 시 ClassCastException이 발생한다.

Code

package study.test.java;

class Person{
    String name;

    public Person(String name) {
        this.name = name;
    }
}

class Student extends Person{
    String grade;
    
    public Student(String name, String grade) {
        super(name);
        this.grade = grade;
    }
    
    void study() {
        System.out.println(name + "이(가) 공부 중입니다.");
    }
}

public class CastingTest {
    public static void main(String[] args) {

        Person person = new Student("도리도리", "1학년");

        // 업 캐스팅을 통해 Student 객체를 Person 타입의 참조 변수에 할당
        // 이 상태에서는 Student 객체의 study 메서드를 호출할 수 없다.
        
        // 명시적으로 다운 캐스팅
        Student student = (Student) person; 
        student.study(); // 이제 study 메서드를 호출할 수 있다.

        // 만약 person이 원래 Student 객체를 참조하지 않았다면 다음과 같은 캐스팅은 ClassCastException을 발생시킬 것이다.
        // Teacher teacher = (Teacher) person; // 이런 코드는 ClassCastException을 발생시킵니다.
    }
}

위의 코드에서는 Person 타입의 참조 변수 person이 Student 객체를 참조하고 있기 때문에 안전하게 다운 캐스팅을 수행할 수 있다. 하지만 만약 person이 Student 타입의 객체를 참조하고 있지 않다면, 다운 캐스팅을 시도할 때 ClassCastException이 발생한다.

DownCasting을 사용할 때에는 항상 주의해야 한다. 무분별하게 캐스팅을 시도하면 실행 시 예외가 발생할 수 있다. 그렇기 때문에, 가능하다면 instanceof 연산자를 사용하여 안전한 캐스팅을 위한 확인 작업을 수행하는 것이 좋다.

profile
Step by Step goes a long way. 꾸준하게 성장하는 개발자 강민승입니다.

0개의 댓글