728x90

다형성(Polymorphism)

- 같은 타입이지만 실행 결과가 다양한 객체 대입 가능한 성질

- 조상 타입의 참조변수로 자손 타입의 객체를 다룰 수 있는 것이 다형성

 

예제1)

public class Ex7_7 {
    public static void main(String[] args) {
        // 조상타입의 참조변수로 자손타입의 객체를 다룰 수 있는 것이 다형성
        // 반대로 자손타입의 참조변수로 조상타입의 인스턴스를 참조할 수는 없다.
        Car car = null; // 조상 타입의 참조변수
        FireEngine fe = new FireEngine(); // 실제 인스턴스가 무엇인지가 중요
       
        car = fe; // 자손 → 조상으로 형변환. 형변환 생략됨
        car.drive();
       
        FireEngine fe2 = null; // 자손 타입의 참조변수
        fe2 = (FireEngine) car; // 조상 → 자손으로 형변환. 형변환 생략불가.
        fe2.drive();
        fe2.water();
    }
}

class Car {
    String color;
    int door;
   
    void drive() {
        System.out.println("운전중!");
    }
   
    void stop() {
        System.out.println("정지.");
    }
}

class FireEngine extends Car {
    void water() {
        System.out.println("물 뿌리는 중!");
    }
}
 

 

예제1은 문제없이 잘 동작된다.

예제2는 자손 타입의 참조변수로 조상 타입의 인스턴스를 참조할 수 없다는 사항에 위배된다.

 

예제2)

public class Ex7_7 {
    public static void main(String[] args) {
        // 조상타입의 참조변수로 자손타입의 객체를 다룰 수 있는 것이 다형성
        // 반대로 자손타입의 참조변수로 조상타입의 인스턴스를 참조할 수는 없다.
        Car car = new Car(); // 조상 인스턴스
        FireEngine fe = (FireEngine) car; // Car cannot be cast to FireEngine
        fe.drive();
    }
}

class Car {
    String color;
    int door;
   
    void drive() {
        System.out.println("운전중!");
    }
   
    void stop() {
        System.out.println("정지.");
    }
}

class FireEngine extends Car {
    void water() {
        System.out.println("물 뿌리는 중!");
    }
}
 

 

예제3)

public class Polymorphism {
    public static void main(String[] args) {
        // 조상타입의 참조변수로 자손타입의 객체를 다룰 수 있는 것이 다형성
        // 반대로 자손타입의 참조변수로 조상타입의 인스턴스를 참조할 수는 없다.
        Car car = null// 조상 타입의 참조변수
        FireEngine fe = new FireEngine(); // 실제 인스턴스가 무엇인지가 중요
 
        car = fe; // 자손 → 조상으로 형변환. 형변환 생략됨
        car.drive(); // 부모 타입에 선언된 변수와 메소드만 사용 가능
 
        FireEngine fe2 = null// 자손 타입의 참조변수
        if(car instanceof FireEngine){ // 먼저 자식 타입인지 확인 후 강제 타입 실행.
            System.out.println("===== 객체 타입 확인 =====");
            fe2 = (FireEngine) car; // 조상 → 자손으로 형변환. 형변환 생략불가
            fe2.drive();
            fe2.water(); // 자식 타입에 선언된 변수와 메소드를 다시 사용해야 하는 경우
        }
 
        Car car1 = new FireEngine(); // 부모 클래스 변수 = 자식 클래스 타입;
        car1.drive(); // 변환 후에는 부모 클래스 멤버만 접근 가능
 
        System.out.println("===== 상속 처리 =====");
        FireEngine fe3 = new FireEngine();
        fe3.drive();
        fe3.water();
 
        System.out.println("===== 부모 타입 =====");
        Car car2 = new Car();
        // 자식타입의 참조변수로 부모타입의 인스턴스를 참조할 수는 없다.
        FireEngine fe4 = (FireEngine) car2;
        fe4.drive();
 
    }
}
 
class Car {
    String color;
    int door;
 
    void drive() {
        System.out.println("운전중!");
    }
 
    void stop() {
        System.out.println("정지.");
    }
}
 
class FireEngine extends Car {
    void water() {
        System.out.println("물 뿌리는 중!");
    }
}
 

 

 

예제4)

상위클래스 타입의 변수가 복수의 하위클래스 객체를 참조할 수 있도록 하는 것을 다형성이라 한다.

- Product 가 상위 클래스, Tv, Computer, Audio 는 하위 클래스

import java.util.ArrayList;
 
class Product {
    int price;            // 제품의 가격
    int bonusPoint;    // 제품구매 시 제공하는 보너스점수
 
    public Product(int price) {
        this.price = price;
        this.bonusPoint = (int)(price / 10.0);
    }
 
    public Product() {
    }
}
 
class Tv extends Product {
    public Tv() {
        // 조상 클래스의 생성자 Product(int price)를 호출.
        super(100);
    }
 
    @Override
    public String toString(){
        // Object 클래스의 toString()을 오버라이딩한다.
        return "Tv";
    }
}
 
class Computer extends Product {
    public Computer() {
        // 조상 클래스의 생성자 Product(int price)를 호출.
        super(200);
    }
 
    @Override
    public String toString() {
        // Object 클래스의 toString()을 오버라이딩한다.
        return "Computer";
    }
}
 
class Audio extends Product {
    public Audio() {
        // 조상 클래스의 생성자 Product(int price)를 호출.
        super(50);
    }
 
    @Override
    public String toString() {
        // Object 클래스의 toString()을 오버라이딩한다.
        return "Audio";
    }
}
 
class Buyer {
    int money = 1000;      // 소유금액
    int bonusPoint = 0// 보너스점수
    ArrayList<Product> cart = new ArrayList<>();// 구입한 제품을 저장하기 위한 배열
 
    void buy(Product p) { // 매개 변수가 Product 타입의 참조변수
        if(money < p.price) {
            System.out.println("잔액이 부족하여 물건을 살 수 없습니다.");
            return;
        }
 
        money -= p.price;             // 가진 돈에서 구입한 제품의 가격을 뺀다.
        bonusPoint += p.bonusPoint;   // 제품의 보너스 점수를 추가한다.
        cart.add(p);                // 제품을 ArrayList<Product> cart에 추가한다.
        System.out.print(p + "를 구입하셨습니다.");
        System.out.println("현재 잔액은 " + money + " 만원입니다.");
    }
 
    void summary() {                  // 구매한 물품에 대한 정보를 요약해서 보여 준다.
        int sum = 0;                 // 구입한 물품의 가격합계
        String itemList ="";         // 구입한 물품목록
 
        // 반복문을 이용해서 구입한 물품의 총 가격과 목록을 만든다.
        for(int i=0; i < cart.size();i++) {
            sum += cart.get(i).price;
            if(i == cart.size() -1){
                itemList += cart.get(i) + " ";
            } else {
                itemList += cart.get(i) + ", ";
            }
        }
        System.out.println("구입하신 물품의 총 금액은 " + sum + "만원입니다.");
        System.out.println("구입하신 제품은 " + itemList + "입니다.");
    }
}
 
public class Ploymorphism {
    public static void main(String[] args) {
        Buyer b = new Buyer();
 
        b.buy(new Tv());
        b.buy(new Computer());
        b.buy(new Audio());
        b.summary();
    }
}
 

 

 

블로그 이미지

Link2Me

,