본문으로 바로가기

1. 타입 변환과 다형성

다형성

동일한 타입을 사용하지만 다양한 결과가 나오는 성질

하나의 타입에 대입되는 객체에 따라서 실행 결과가 다양한 형태로 나오는 성질

 

타입 변환

데이터 타입을 다른 데이터 타입으로 변환하는 행위

구현 객체가 인터페이스 타입으로 변환되는 것 (자동 타입 변환)

자동 타입 변환을 이용하면 필드의 다형성과 매개 변수의 다형성을 구현 가능

 

다형성을 구현하는 기술(Java)

상속 :  같은 종류의 하위 클래스를 만드는 기술

인터페이스 :  사용 방법이 동일한 클래스를 만드는 기술

 

2. 다형성을 왜 구현하나요?

ButtonA 라는 클래스를 활용하여 어떤 프로그램을 개발한다고 가정합니다.

public class ButtonA {
    public void buttonClickEvent() {
        System.out.println("Button A Click");
    }
}
ButtonA buttonA = new ButtonA();
buttonA.buttonClickEvent();

 

개발 중 혹은 개발 테스트 중에 확인해보니 ButtonA 클래스에 문제가 있다는 것을 확인 합니다.

그래서 다른 클래스인 ButtonB 클래스로 변경하기로 합니다.

public class ButtonB {
    private boolean check;

    public ButtonB(boolean check) {
        this.check = check;
    }

    public void click(boolean check) {
        if(!this.check == check) {
            this.check = check;
            if(this.check == true) {
                System.out.println("Button B ON");
            } else {
                System.out.println("Button B OFF");
            }
        }
    }
}

 

ButtonB 클래스의 생성자와 메소드는 이름매개 변수가 다릅니다.

즉 사용 방법이 다르기 때문에 ButtonA 클래스가 사용된 곳을 찾아서 모두 변경해야 합니다.

// ButtonA buttonA = new ButtonA();
// buttonA.buttonClickEvent();

ButtonB buttonB = new ButtonB(false);
buttonB.click(true);
buttonB.click(false);

 

하지만 ButtonA와 ButtonB의 사용 방법(메소드 이름, 매개변수 등)이 같았다면

특별한 코드의 수정 필요 없이 객체 생성 부분만 ButtonA에서 ButtonB로 변경만 하면 됩니다. 

// Button button = new ButtonA();
Button button = new ButtonB(); // 객체 생성 부분만 수정

button.buttonClickEvent();

 

따라서 인터페이스추상 클래스를 활용하여 다형성을 구현합니다.

 

3. 필드 다형성

인터페이스 CPU

public interface CPU {
    void printSpec();
}

 

구현 클래스 InterCPU

public class IntelCPU implements CPU{
    private String modelName;
    private int coreCnt;

    public IntelCPU(String modelName, int coreCnt) {
        this.modelName = modelName;
        this.coreCnt = coreCnt;
    }

    @Override
    public void printSpec() {
        System.out.println("---- Intel CPU STATUS ----");
        System.out.println("모델명: " + this.modelName);
        System.out.println("코어 수: " + this.coreCnt);
        System.out.println("---- Intel CPU STATUS ----");
        System.out.println();
    }
}

 

구현 클래스 AmdCPU

public class AmdCPU implements CPU{
    private String modelName;
    private int coreCnt;

    public AmdCPU(String modelName, int coreCnt) {
        this.modelName = modelName;
        this.coreCnt = coreCnt;
    }

    @Override
    public void printSpec() {
        System.out.println("---- AMD CPU STATUS ----");
        System.out.println("모델명: " + this.modelName);
        System.out.println("코어 수: " + this.coreCnt);
        System.out.println("---- AMD CPU STATUS ----");
        System.out.println();
    }
}

 

클래스 Computer

public class Computer {
    CPU cpu;

    public void printCPU() {
        cpu.printSpec();
    }
}

 

실행

Computer computer = new Computer();

computer.cpu = new IntelCPU("intel-001", 8);
computer.printCPU();

// 필드 객체 교체
computer.cpu = new AmdCPU("amd-001", 4);
computer.printCPU();

결과값

 

4. 매개 변수 다형성

※ 인터페이스 CPU, 구현 클래스 IntelCPUAmdCPU는 동일합니다.

public class Main {
    public static void main(String[] args) {
        CPU cpu = new IntelCPU("intel-001", 8);
        print(cpu);

        cpu = new AmdCPU("amd-001", 4);
        print(cpu);
    }

    // 매개변수 자동 형 변환
    public static void print(CPU cpu) {
        cpu.printSpec();
    }
}