본문 바로가기

Language/Java

[JAVA] 다형성(polymorphis)

1. 정의

다형성이란, 하나의 객체가 여러가지 타입을 가질 수 있는 것을 말한다. 

Java에서는 부모 클래스의 참조 변수가 자식 클래스의 인스턴스를 참조할 수 있도록 하는 것으로 다형성을 구현했다.

만약 Camera class가 factoryCam class의 부모 클래스 라면, 

//Canera가 부모클래스, factoryCam이 자식클래스
Camera FC = new factoryCam();

라고 선언이 가능하고, 위의 동작을 그림으로 표현하면 다음과 같다. 

만약 참조변수와 일반변수의 차이가 헷갈린다면, 밑의 링크를 참조하자. 

https://dalcheonroadhead.tistory.com/68

만약 Camera 클래스에 factoryCam, SpeedCam 이라는 자식 클래스가 있다고 했을 때, 다형성을 이용해 다음과 같이 표현할 수 있다.

//일반 객체 선언
Camera C = new Camera();

// 다형성을 이용한 객체 선언 
Camera FC = new FactoryCam();
Camera SC = new SpeedCam();

**그렇다면 자식클래스의 참조변수가 부모 클래스의 객체를 참조할 수는 없을까? 

없다. java에서는 다형성은 부모 클래스 참조변수로 자식 클래스의 객체를 가리킬때만 사용 가능하다.

 

(2) 다형성 이용한 객체 선언을 배열로 표현하기. 

배열 또한 참조형 타입이다. 배열이 값을 저장하는 원리는 위의 다형성 이용 객체 선언의 원리와 같다. 

배열의 원리를 간단하게 설명하면 다음과 같다. 

다형성 이용한 객체 선언을 배열로 표현하면, 

// 클래스는 자료형의 취급을 받으므로 밑의 문장이 가능하다.
Camera[] cameras = new Camera[3];

Camera[0] = new Camera();
Camera[1] = new FactoryCam();
Camera[2] = new SpeedCam();

2. 특징

다형성을 이용하여 부모 클래스 참조 변수로 자식 클래스 객체를 참조한 경우, 해당 참조변수들은 자식 클래스 고유의 매소드는 사용할 수 없다. (오로지 부모클래스의 공통된 매소드만 사용할 수 있음.)

 

이유? 

선언한 자료형이 부모클래스이기 때문이다. 따라서 자식 클래스 안으로 진입할 수가 없다. 

 

그렇다면, 다형성을 이용한 객체 선언 이후에,  자식 클래스 고유의 변수와 매소드도 사용할려면? 

해당 참조변수가 자식클래스의 객체를 참조하는지 확인하고, 참조한다면, 변수의 자료형을 자식클래스로 형변환 시켜야한다.

 

* 사전 참고 사항 1 (부모 클래스 내부)

// 부모 클래스
public class Camera {
    public String name;
    
    public Camera() {
        this.name = "카메라";
    }

    public void takePicture() {
        // 사진 촬영
        System.out.println(this.name + ": 사진을 촬영합니다.");
    }

    public void recordVideo() {
        // 동영상 녹화
        System.out.println(this.name + ": 동영상을 녹화합니다.");
    }

    public void showMainPicture() {
        System.out.println(this.name + "의 주요 기능 : 사진 촬영, 동영상 녹화");
    }
}

 

*참고사항 2 (자식 클래스 내부)

//FactoryCam
public class FactoryCam extends Camera {
    public FactoryCam() {
        this.name = "공장 카메라";
    }

    public void detectFire() {
        //화재 감지
        System.out.println("화재를 감지합니다.");
    }
    public void showMainPicture() {
        System.out.println(this.name + "의 주요 기능 : 화재 감지");
    }
}
//SpeedCam
public class SpeedCam extends Camera {

    public SpeedCam() {
        this.name = "과속단속 카메라";
    }


    public void checkSpeed() {
        // 속도 체크
        System.out.println("속도를 측정합니다.");
    }

    public void recognizeLicensePlate(){
        // 번호 인식
        System.out.println("차량 번호를 인식합니다.");
    }

    @Override// annotation -> 컴파일 하는 컴퓨터에게 설명하기 위한 주석 (우리가 지금 오버라이딩을 썼다고 알림)

    public void showMainPicture() {
        System.out.println(this.name + "의 주요 기능 : 속도 측정, 번호 인식");
    }
}

 

 

Camera camera = new Camera();
Camera factoryCam = new FactoryCam();
Camera speedCam = new SpeedCam();


//위와 같이 부모 클래스 자료형으로 선언하면, 자식클래스 고유의 매소드는 사용불가        
//  factoryCam.detectFire();
//  speedCam.checkSpeed();
//  speedCam.recognizeLicensePlate();

//사용하게 하려면? 내용물이 자식 클래스 객체가 맞는지 확인
// 맞다면 자료형을 형 변환 (부모 클래스 -> 자식 클래스)

        if (factoryCam instanceof FactoryCam) {
            ((FactoryCam)factoryCam).detectFire();
        }

        if (speedCam instanceof SpeedCam) {
            ((SpeedCam) speedCam).checkSpeed();
            ((SpeedCam) speedCam).recognizeLicensePlate();
        }

**참고**

여기서 if (객체a instanceof 클래스 B ) 은 객체 a가 클래스 B의 객체가 맞는지 확인하는 것이다. 

 

3. 외웠는지 점검

*다형성이란 무엇인지 
참조변수 그림을 통해 표현 

*반대로 자식 클래스의 참조변수가 부모 클래스의 객체를 참조할 수 없을까? 안됨. why? 

(1) 코드로 어떻게 쓰는지 직접 써보기 
(2) 배열로 어떻게 똑같이 나타내는지, 왜 같은 말인지 써보기 
(3) 이때 되는 명령 안되는 명령, 안되는 명령은 왜 안되는지, 안되는 명령 되게 하려면 어떻게 해야하는지 

'Language > Java' 카테고리의 다른 글

[JAVA] Super  (0) 2023.01.28
일반 변수와 참조 변수 바로 알기  (0) 2023.01.28
[JAVA]Overriding(덮어쓰기)  (0) 2023.01.27
Chap07_09 상속(inheritance)  (0) 2023.01.27
Chap07_08 Package 의미 알기 (예시로 Random 이용)  (0) 2023.01.27