JAVA/JAVA 정리

[JAVA] 다형성과 타입 변환

웹코린이 2023. 5. 26. 08:49
728x90

타입 변환이란 타입을 다른 타입으로 변환하는 것으로 JAVA에서는 두가지가 존재한다.

  • 자료형 변환
  • 클래스의 객체 타입 변환

클래스의 형 변환에도 자료형 변환과 똑같이 자동 형 변환과 강제 형 변환이 있다. 하지만 자료형에 비해 타입 변환 범위가 좁다. 클래스 타입의 변환은 서로 상속 관계에 있는 클래스 사이에서만 변환할 수 있다.

 

클래스의 자동 형 변환

 

클래스 자동 형 변환은 상속 관계에 있는 자식 클래스의 객체를 부모 타입의 객체로 변환하는 것을 말한다.

부모 클래스 객체 변수 = new 자식 클래스();  // 1번

부모 클래스 객체 변수 = 자식 객체  // 2번

 

자동 형 변환 예시

	class Parent { }
    class Child extends Parent { }
    
    public class Test01 {
    	public static void main(String[] args) {
        	Parent p1 = new Parent();
            Child c1 = new Child();
            
            Parent p2 = new Parent();
            Parent p3 = new Parent();
            
            if(p3 == c1) { // 모든 자식은 부모 타입이므로 True
            	System.out.println("p3와 c1은 같은 객체를 참조하고 있다.");
            }
        }
    }
    
    // [출력결과]
    // p3와 c1은 같은 객체를 참조하고 있다.

 

강제 형 변환

 

 자식 타입에서는 부모 타입으로 형 변환을 시킬 수 없는데 강제로 자식 타입에서 부모 클래스로 타입 변경을 시키는 것을 '강제 형 변환'이라고 한다. 강제 형 변환의 경우 개발할 때 직접 명시해야만 하는 타입 변환이다. 

 

강제 형 변환 선언 방법

((자식 타입) 부모 타입).메소드(); // 일회성 타입 변환

자식 타입 변수 = (자식 타입) 부모 타입; // 객체 타입 변환

 

강제 형 변환 예시

public class Bike {
	String riderName;
    int wheel = 2;
    
    Bike(String riderName) {
    	this.riderName = riderName;
    }
    
    void info() {
    	System.out.println(riderName + "의 자전거는 " + wheel + "발 자전거입니다.");
    }
    
    void ride() {
		System.out.println("~~");
    }
}

public class FourWheelBike extends Bike {
	FourWheelBike(String riderName) {
    	super(riderName);
    }
    
    @Override
    void info() {
		super.info();
    }
    
    void addWheel() {
    	if(wheel == 2) {
        
        }
    }
}

 

equals 오버라이딩(강제 형변환)

   @Override
   public boolean equals(Object obj) { // equals 오버라이딩
      Point point=(Point)obj;
      if(this.x==point.x) {
         if(this.y==point.y) {
            return true;
         }
      }
      return false;
   }

최상위 클래스인 Object와 Point 클래스를 비교하기 위해 Object 클래스를 다운캐스팅하여 값을 비교한다. Object 클래스는 모든 클래스의 부모 클래스이기 때문에 가능한 방법이다.

 

캐스팅(Casting)

  1. 업 캐스팅(up casting)
    • 자식 값을 부모 타입으로 형 변환시킨 값
  2. 다운 캐스팅(down casting) 
    • up casting된 객체를 자식 타입으로 형변환시킨 값

 

다형성

 

다형성이란 ?

 

 하나의 타입으로 다양한 객체를 사용할 수 있는 것을 뜻한다. 부모 클래스의 타입 하나로 여러 가지 자식 객체들을 참조하여 사용함으로써 다형성을 구현할 수 있다. 따라서 클래스 타입 변환이 존재하는 이유는 다형성을 구현하기 위함이라고 할 수 있다. 하지만 다형성을 구현하는 방법의 하나일 뿐, 혼자 다형성을 완전히 구해내는 것이 아니라 [ 상속, 메소드 오버라이딩, 클래스 타입 변환] 이 세가지 특징이 힘을 합쳐야 합니다.

 

 

 

다형성의 장점

 

 객체가 특정 클래스의 필드가 되면서, 하나의 부품처럼 사용될 수도 있다. 이때, 부품을 교체할 일이 생긴다면 우리는 다형성을 구현함으로써 코드 수정을 최소화 할 수 있다.

 

다형성 구현 방법

public class Computer { // 부모 클래스
	void powerOn() {
    	System.out.println("컴퓨터가 켜졌습니다.");
    }
    
    void powerOff() {
    	System.out.println("컴퓨터가 종료됩니다.");
    }
}

public class Samsong extends Computer {
	@Override
    void powerOn() {
    	System.out.println("삼송");
    }
}

public class ComputerRoom {
	Samsong computer1;
    Samsong computer2;
    
    void allPowerOn() {
    	computer1.powerOn();
        computer2.powerOn();
    }
    
    void allPowerOff() {
    	computer1.powerOff();
        computer2.powerOff();
    }
}

public class Test01 {
	public static void main(String[] args) { 
    	ComputerRoom cr = new ComputerRoom();
        cr.computer1 = new Samsong();
        cr.computer2 = new Samsong();
        
        cr.allPowerOn();
        cr.allPowerOff();
    }
}

// [출력 결과]
// 컴퓨터가 켜졌습니다.
// 삼송
// 컴퓨터가 켜졌습니다.
// 삼송
// 컴퓨터가 종료됩니다.
// 컴퓨터가 종료됩니다.

위와 같이 cr.allPowerOn(); 을 실행해도 알아서 자식이 구현한 메소드가 실행되는 현상을 '동적 바인딩'이라고 한다. 이것을 '다형성이 실현 되었다' 라고한다.

 

또한, 자식 클래스는 모두 부모 타입이기에 자식 값을 부모 타입으로 생성할 수 있지만, 반대로는 불가능하다. (컴파일 오류 발생)

class Parent { }
class Child extends Parent { }

Parent pa = new Parent(); // O
Child ch = new Child(); // O
Parent pa = new Child(); // O
Child ch = new Parent(); // X 오류 발생

 

instanceof 연산자

  • instanceof 기준으로 왼쪽 객체가 생성될 때 오른쪽 타입으로 생성되었는지 확인하는 연산자이다.
  • 맞으면 True, 아니면 False를 반환하며 만약 null을 가리키고 있으면 false를 반환한다.
  • Ex) a instanceof A ==> a가 A 타입이면 True, 아니면 False 반환

instanceof 예제

class Parent {}
class Child extends Parent {}

public class Test01 {
	public static void main(String[] args) {
    	Parent parent = new Parent();
        Child child = new Child();
        
        System.out.println(parent instanceof Parent);  // 부모가 본인집을 찾았으니 true
        System.out.println(child instanceof Parent);   // 자식이 상속받은 집을 찾았으니 true
        System.out.println(parent instanceof Child);   // 자식 집은 자식 집이지 부모 집이 아니므로 false
        System.out.println(child instanceof Child);    // 자식이 본인 집을 찾았으니 true
    }
}

instanceof 연산자와 '==' 연산자의 차이

  • A instanceof B : 객체 변수 A가 객체의 타입 B로 생성된 것인지 확인한다.
  • C == D : 객체 변수 C와 객체 변수 D가 같은 객체를 참조하고 있는지를 확인한다.
728x90