ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java | Object Type Casting 객체 형 변환 & Instanceof
    JAVA/JAVA 2020. 2. 5. 17:25

    Object Type Casting 객체 형 변환

    객체간 자료형을 변환하는 것

    • 인터페이스, 배열, 클래스에 적용
    • 상속 관계 때문에 만들어진 기능

     


    Upcasting 묵시적 객체 형 변환

    하위 클래스에서 상위 클래스로 자료형을 변환하는 것

    • 하위 클래스는 이미 상위 클래스를 상속받아서
      상위 클래스의 모든 변수와 기능을 가지고 있기 때문에
      하위 클래스의 객체를 상위 클래스의 자료형으로 변환해서 생성할 수 있음
    • 하위 클래스의 객체를 상위 클래스의 자료형으로 선언하기만 하면 됨
    • 상위 클래스형 변수(ex. 배열)에 대입되는 경우에도 묵시적 형 변환이 일어남
    • 상위 클래스형으로 생성된 객체는 상위 클래스의 멤버 변수와 메소드만 사용 가능
      단, 메소드가 하위 클래스에서 오버라이딩되었다면 오버라이딩된 메소드 호출
    • 상위 클래스에서는 하위 클래스로 묵시적 형 변환을 할 수 없음

    형식

    상위클래스형 하위클래스 객체명 = new 하위클래스형();
    
    // SuperClass sub = new SubClass();

    ※ 클래스형과 클래스의 자료형, 인스턴스형과 인스턴스 자료형은 모두 비슷한 의미로 사용


    예제

    package j200205;
    
    // Shape_상위 클래스
    class Shape {
    
        // 모든 도형에서 사용하는 메소드
        void draw() {
            System.out.println("Shape");
        }
    
        // Shape 전용 메소드
        void shapeDraw() {
            System.out.println("Shape");
        }
    }
    
    // Point_하위 클래스
    class Point extends Shape {
        // 오버라이딩
        void draw() {
            System.out.println("Point");
        }
    
        // Point 클래스 메소드
        void pointDraw() {
            System.out.println("Point");
        }
    }
    
    public class ShapeTest {
    
        public static void main(String[] args) {
    
            // 클래스형에 맞는 객체 생성
            Shape s = new Shape();
            Point p = new Point();
    
             // 묵시적 형변환_객체 생성
             Shape sp = new Point();
    
            // 각자 메소드 출력
            s.shapeDraw();    // Shape
            p.pointDraw();    // Point
            sp.shapeDraw();   // Shape
            
            sp.draw();        // Point, 오버라이딩된 메소드가 호출됨
            // sp.pointDraw() 메소드는 호출 불가
    
            // 묵시적 형변환_배열 요소에 대입
            // 배열에는 같은 자료형만 저장될 수 있는데
            // 하위 클래스 객체는 상위 클래스 배열에 묵시적으로 들어갈 수 있음
    
            // Shape 자료형 배열 생성 및 초기화
            Shape[] sh = new Shape[3];
            sh[0] = s; // Shape 
            sh[1] = p; // Point
            sh[2] = sp; // Shape
    
            // 배열에 객체들이 잘 저장됐는지 확인
            for (int i = 0; i < sh.length; i++) {
                sh[i].draw();
            }
    
            /*
            Shape
            Point
            Point
            */
        }
    
    }

    Instanceof

    왼쪽에 있는 객체가 오른쪽 클래스의 인스턴스(객체)인지 확인하는 예약어
    맞다면 true, 아니라면 false 반환


    형식

    객체명 instanceof 클래스명

    예제

    package j200205;
    
    class Shape {
    
    	// 위의 예제와 동일
    
    }
    
    class Point extends Shape {
    	
    	// 위의 예제와 동일
    
    }
    
    
    public class ShapeTest {
    
        // Shape 객체 클래스형 확인 메소드
        static void whoAreYou(Shape sh) {
        
            // 객체가 Shape형인지 확인
            if(sh instanceof Shape)
                System.out.println("I am Shape");
            else
                System.out.println("I am not Shape");
                
            // Point형인지 확인
            if(sh instanceof Point)
                System.out.println("I am Point");
            else
                System.out.println("I am not Point");
                
        }
    
        public static void main(String[] args) {
    
            // 객체 생성
            Shape s = new Shape();
            Point p = new Point();
            Shape sp = new Point();
    
            Shape[] sh = new Shape[3];
            sh[0] = s; // Shape
            sh[1] = p; // Shape + Point
            sh[2] = sp;
    
            // 객체 자료형 확인
            for (int i = 0; i < sh.length; i++) {
                sh[i].draw();
                whoAreYou(sh[i]);
            }
            
            /*
            Shape
            I am Shape
            I am not Point
            Point
            I am Shape
            I am Point
            Point
            I am Shape
            I am Point
            */
        }
    
    }

    ※ Shape 클래스로 생성된 객체는 Point 클래스의 객체가 아니지만,
    Point 클래스로 생성된 객체는 Point 클래스의 객체이면서 동시에 Shape 클래스 객체임
    자동 형 변환으로 생성된 객체 역시 Point 클래스로 생성된 객체이면서 Shape 클래스 객체임


    Downcasting 명시적 객체 형 변환

    상위 클래스로 생성된 객체를 하위 클래스로 강제로 형 변환하는 것
    상위 클래스로 형 변환되었던 하위 클래스를 다시 하위 클래스형으로 형 변환

    • 상위 클래스에서 하위 클래스로 형변환을 할 때는 하위 클래스 자료형을 명시해야 함
    • instanceof 예약어로 상속 관계를 확인하고 형 변환을 해야 실행 오류를 방지할 수 있음
    • 명시적 형 변환시 상속 관계가 아니더라도 클래스 자료형만 맞으면
      컴파일 에러는 발생하지 않지만, 프로그램을 실행하면 실행 에러 발생

    형식

    하위클래스형 하위클래스 객체명 = (하위클래스형) 상위클래스 객체명;
    // SubClass sub = (SubClass) superClass; 

    예제

    package j200205;
    
    class Shape {
    
        void draw() {
            System.out.println("Shape");
        }
    
        void shapeDraw() {
            System.out.println("Shape");
        }
    }
    
    class Point extends Shape {
    
        void draw() {
            System.out.println("Point");
        }
    
        void pointDraw() {
            System.out.println("Point");
        }
    }
    
    public class ShapeTest {
    
        public static void main(String[] args) {
    
            // 묵시적 형 변환으로 Shape 형 객체 생성
            Shape sp = new Point();
    
            if (sp instanceof Point) {
                // sp 객체가 원래 Point 클래스로 생성된 것인지 확인
                System.out.println("Point 클래스 객체!");
    
                // 명시적 형 변환
                Point pp = (Point) sp;
                pp.pointDraw();
                // Point형 객체가 되었기 때문에 pointDraw() 메소드에 접근 가능
            }
            
            /*
            Point 클래스 객체!
            Point
            */
        }
    }

    객체 형 변환과 객체의 클래스형을 확인하는 instanceof 예약어에 대해 살펴보았습니다.

    객체 형 변환의 경우 자바의 굉장히 많은 곳에서 사용된다고 하기 때문에 꼭 알아둘 필요가 있겠습니다.

    묵시적 형 변환시 상위 클래스의 멤버 변수 및 메소드에만 접근할 수 있지만
    상위 클래스의 메소드를 하위 클래스에서 재정의한 경우 오버라이딩 메소드가 호출된다는 점이 특이한 것 같습니다.

    instanceof의 경우 해당 객체의 클래스형을 확인할 수 있으므로 다양한 경우에서 유용하게 사용할 수 있겠습니다.

    댓글

Designed by Tistory.