도찐개찐

[JAVA] 다형성(polymorphism) 본문

JAVA

[JAVA] 다형성(polymorphism)

도개진 2022. 7. 7. 11:12

다형성(polymorphism)

다형성은 자바 개발에서 상당히 많이 활용되는 문법이다. 상속과 관련이 깊다.

여러 가지 형태를 가질 수 있는 능력

이라고 정의된다. 이렇게 보면 좀 추상적인데, 실제 코드 작성에서 사용되는 개념에 비추어 정확히 표현하면

조상 클래스의 참조 변수로 자손 클래스의 객체를 다룰 수 있는 특징

이다.

 

Ex)

class Tv {
    boolean power; // 전원
    int channel; // 채널

    void power(){power = !power;} // 전원 on/off
    void channelUp(){++channel;} // 채널 올리기 
    void channelDown(){--channel;} // 채널 내리기
}

class SubtitleTv extends Tv { // Tv 클래스를 상속받은 SubtitleTv
    String text;
    void Subtitle(){} // 자막
}

Tv 클래스와 이를 상속받은 SubtitleTv 클래스가 있다. 이때

Tv t = new SubtitleTv();
// SubtitleTv c = new Tv(); 참고로 반대는 사용할 수 없음

처럼 Tv(조상)의 참조변수로 SubtitleTv(자손) 객체에 접근하는 것을 다형성이라고 말한다.

SubtitleTv c = new SubtitleTv();

SubtitleTv의 참조변수로 SubtitleTv의 객체에 접근하는 것과 어떤 차이가 있을까.

 

t의 멤버 변수 활용도가 c의 멤버 변수보다 제한적이라고 말할 수 있다. 왜냐하면 Tv의 자손 클래스인 SubtitleTv는 Tv가 가지고 있는 인스턴스와 메서드를 품고 있는 한편 자신의 클래스에서 새롭게 선언한 멤버 변수까지 가지고 있다. 반면 조상인 Tv는 SubtitleTv에서 선언된 멤버 변수를 품고 있지 않다. 따라서

t.power(); // 가능
t.Subtitle(); // 불가능

c.power(); // 가능
c.Subtitle(); // 가능

다형성의 효율적 활용

제한된 멤버 변수만을 품을 수 있는데 왜 굳이 조상 클래스의 참조 변수로 자손 클래스의 객체에 접근할까. 코드의 효율성을 높일 수 있기 때문이다. 아래는 매개변수의 다형성을 이용한 예시다.

 

  • class
    • Product // 조상 클래스
    • Tv // 자손 클래스
    • Computer // 자손 클래스
    • Buyer

이들 클래스를 이용해 메인 메서드에서 객체를 생성하고 구매 후 남은 돈을 출력하는 프로그램이다.

class Product {
    int price; // 제품 가격

    Product(int price){ // 생성자
    this.price = price;
    }
}

class Tv extends Product {
    Tv() {
        //조상 클래스의 생성자 Product(int price)를 호출.
        super(100); // Tv의 가격을 100만원으로 한다.
    }
    @Override
    public String toString() {
        //Object 클래스의 toString()을 오버라이딩한다.
        return "TV";
    }
}

class Computer extends Product {
    Computer() {
        super(200);
    }
    @Override
    public String toString() {
        return "Computer";
    }
}

class Buyer { // 고객
    int money = 1000; // 소유금액
    void buy(Product p) {
    // 매개 변수가 Product 타입의 참조변수. Product 클래스의 자손 클래스 Tv, Computer의 참조변수를 한번에 매개변수로 받아들일 수 있음.
    // 앞으로 다른 제품 클래스를 추가할 때 Product클래스를 상속받기만 하면, buy(Product  p)메서드의 매개변수로 받아들여질 수 있다.
    if(money<p.price) {
        System.out.println("잔액이 부족하여 물건을 살수 없습니다.");
        return;
    }
    money -= p.price; // 가진 돈에서 구입한 제품의 가격을 뺀다.
    }
}
public class PolyArgumentTest {
    public static void main(String[] args) {
        Buyer b = new Buyer();
        Tv tv = new Tv();
        Computer com = new Computer();

        b.buy(tv); // tv 구매
        b.buy(com); // computer 구매
    }
}

결과값

현재 남은 돈은 700만원입니다.

Buyer 클래스에서 buy(Product p) 메서드를 선언하는 방식을 주목해야 한다. Tv, Computer 클래스의 공통적인 조상 클래스인 Product 타입의 참조 변수를 선언했다. 이러면 buy(Product p) 메서드는 Product 클래스를 상속받는 모든 자손 클래스의 참조변수를 매개변수로 받아들일 수 있게 돼 효율적인 코딩이 가능해진다.

 

출처 : https://change-words.tistory.com/24

 
728x90

'JAVA' 카테고리의 다른 글

[JAVA] 중첩클래스(Nested Class)  (0) 2022.07.07
[JAVA] 제네릭스(Generics)  (0) 2022.07.07
[JAVA] instanceof  (0) 2022.07.07
[JAVA] 클래스 형변환  (0) 2022.07.07
[JAVA] 상속(Inheritance)  (0) 2022.07.06
Comments