열정 실천

[JAVA] 객체의 형변환 - 업캐스팅(묵시적 형변환), 다운캐스팅(명시적 형변환) 본문

개발 공부/JAVA

[JAVA] 객체의 형변환 - 업캐스팅(묵시적 형변환), 다운캐스팅(명시적 형변환)

구운오니 2024. 10. 7. 19:31
728x90
묵시적 형변환 (업캐스팅) 

 

 :: 자식 클래스의 객체를 부모 클래스 타입으로 변환

SuperClass A = new SubClass(); 

 

자식 클래스는 부모 클래스를 확장하므로, 자식 클래스의 객체는 부모 클래스 타입으로 자동으로 변환될 수 있다. 업캐스팅은 암묵적으로 수행되고, 이 객체는 자식 클래스에만 있는 메소드에는 접근할 수 없게 된다.

class SuperClass {

    public void draw() {
        System.out.println("A");
        draw();
    }
    
    public void paint() {
        System.out.println("B"); //3
        this.draw(); //4
    }
}

class SubClass extends SuperClass {

    public void paint() {
    	super.paint(); //2
        System.out.println("C"); //6
        draw(); // 7 
    }
    
    public void draw() {
        System.out.println("D"); //5 //8 //10
    }
}

public class Main {
    public static void main(String[] args) {
        SuperClass a = new SubClass(); // 업캐스팅
        
        a.paint();    //1
        a.draw();     //9
         
    }
}

 

//1 main 함수 :: 자식 클래스의 paint() 함수를 실행한다. 객체 변수 a는 SuperClass 타입의 변수지만, 실제로는 SubClass 객체를 참조하고 있기 때문이다. 

 

//2 자식의 paint() ::  super.paint()는 SUPER 키워드로 인해 부모의 paint()함수를 실행한다. 

 

//3 부모의 paint() :: "B"를 출력한다.

 

//4 부모의 paint()  :: draw()함수를 실행하게 되는데 이 draw함수는 자식클래스에서 재정의 되었기 때문에 자식 클래스의 draw()를 호출하게 된다. 

**this는 현재 객체를 참조하는 키워드이다. a 객체를 참조하고 있다. 

 

//5 자식의 draw() :: "D"를 출력한다.

 

//6 자식의 paint() :: "C"를 출력한다.

 

//7 자식의 paint() :: //4와 같은 이유로 자식의 draw()를 호출한다. 

 

//8 자식의 draw() :: "D"를 출력한다.

 

//9 main 함수 :: //4,//7과 같은 이유로 자식의 draw()를 호출한다. 

 

//10 자식의 draw() :: "D"를 출력한다.

 

결국 출력은 

B

D

C

D

D

이다. 

 

쉽게 말해서

업캐스팅된 이 객체는 부모의 자료형이지만 자식의 생성자로 생성되어 상속받은 모든 함수들이 재정의된다. 

따라서 부모에게 상속받은 함수가 실행될 때에 재정의된 자식의 함수가 실행되는 것이다. 

자식에게는 없지만 부모클래스에서만 정의된 메소드도 접근이 가능하다. 

하지만 부모에게는 없고 자식에게만 있는 메소드에는 접근이 불가능하다. 

 

 

 

 

 

 

 

 

 

 

 

명시적 형변환 (다운캐스팅) 

 

:: 부모 클래스 타입의 객체를 자식 클래스 타입으로 변환

 

SubClass B = new (SubClass)SuperClass();

 

이 경우, 명시적인 형변환이 필요하다. 다운캐스팅을 사용할 때는 객체가 실제로 해당 자식 클래스의 인스턴스인지 확인하는 것이 중요하다. 그렇지 않으면 ClassCastException이 발생할 수 있습니다. instanceof 연산자를 사용하여 확인할 수 있다. (B instanceof SubClass //true or false)

 

class Animal {
    public void makeSound() {
        System.out.println("Some sound");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Bark");
    }
    
    public void fetch() {
        System.out.println("Fetching...");
    }
}

public class Main {
    public static void main(String[] args) {
    
        Animal animal = new Dog(); // 암시적 형변환 : 업캐스팅
        dog.fetch();  // 컴파일 오류, Dog 클래스에만 있는 함수에는 접근 불가
        
        Dog dog = (Dog) animal; // 명시적 형변환 : 다운캐스팅
        
        
        
        Animal animal = new Animal(); // Animal 객체 생성
		
        Dog dog = (Dog) animal; // 잘못된 다운캐스팅, ClassCastException 발생
        
        
         // 안전한 다운캐스팅
        if (animal instanceof Dog) {
			Dog dog = (Dog) animal;
			dog.fetch(); // "Fetching..." 출력
		} else {
			System.out.println("animal은 Dog의 인스턴스가 아닙니다.");
		}
   }
}

 

 

 

 

 

 

 

객체 형변환의 핵심!

 

객체의 묵시적 형변환(업캐스팅)은 사용할 수 있는 멤버 변수를 제한하는 것

객체의 명시적 형변환(다운캐스팅)은 제한된 멤버 변수를 다시 사용할 수 있게 만드는 것

 

객체의 형변환을 통해 객체 지향 프로그래밍의 핵심 개념인 "하나의 인터페이스로 여러 구현을 다룰 수 있다"

이를 통해 코드의 유연성과 재사용성이 크게 향상된다.

 

728x90