티스토리 뷰

반응형

 

오늘은 객체지향의 꽃인

다형성에 대해 학습해보자.

 


🤔 다형성(polymorphism)이란?

✔ 조상 타입 참조 변수로 자손 타입 객체를 다루는 것

✔ 자손 타입의 참조변수로 조상 타입의 객체를 가리킬 수 없다.

 

 

 

조상 타입 참조 변수로 자손 타입 객체를 다루는 것

Tv t = new SmartTv(); // 타입 불일치

위와 같이 Tv (조상 타입 참조 변수) 리모콘으로

SmartTV(자손 타입 객체)를 다루는 것을 다형성이라고 한다.

 

 

자손 타입의 참조변수로 조상 타입의 객체를 가리킬 수 없다.

Tv t = new SmartTv(); // 허용
SmartTv s = new Tv(); // 허용 안 됨. // 자손 타입의 참조변수로 조상 타입의 객체를 가리킬 수 없다.

SmartTv 리모컨 버튼 6(Tv버튼 5개 + 1)개, Tv 리모컨 버튼 5개

6개 버튼 리모컨으로 5개 Tv 생성 불가

버튼 하나가 비니까!

 


 

🤔 참조변수의 형변환이란?

✔ 사용할 수 있는 멤버의 갯수를 조절하는 것

✔ 조상 자손 관계의 참조변수는 서로 형변환 가능

 

 

조상 자손 관계의 참조변수는 서로 형변환 가능

class Car {
    String color;
    int door;

    void drive() { // 운전하는 기능
        System.out.println("drive, Brrr~");
    }

    void stop() { // 멈추는 기능
        System.out.println("stop!!");
    }
}

class FireEngine extends Car { // 소방차
    void water() { // 물을 뿌리는 기능
        System.out.println("water!!");
    }
}

class Ambulance extends Car {}

public class T2 {
    public static void main(String[] args) {
        FireEngine f = new FireEngine();
        Car c = (Car)f; // OK. 조상인 Car타입으로 형변환(생략가능)
        FireEngine f2 = (FireEngine)c; // OK. 자손인 FireEngine타입으로 형변환(생략가능)
        Ambulance a = (Ambulance)f; // 에러. 상속관계가 아닌 클래스 간의 형변환 불가

    }
}

 

 

참조변수의 형변환 예제


class Car {
    String color;
    int door;

    void drive() { // 운전하는 기능
        System.out.println("drive, Brrr~");
    }

    void stop() { // 멈추는 기능
        System.out.println("stop!!");
    }
}

class FireEngine extends Car { // 소방차
    void water() { // 물을 뿌리는 기능
        System.out.println("water!!");
    }
}

class Ambulance extends Car {}

public class T2 {
    public static void main(String[] args) {
        Car car = null;
        FireEngine fe = new FireEngine();
        FireEngine fe2 = null;
        
        fe.water();
        car = fe; // car = (Car) fe; 에서 형변환이 생략됨.
        car.water(); // 컴파일 에러!! Car 타입의 참조변수로는 water()를 호출할 수 없다.
        fe2 = (FireEngine) car; // 자손타입 <- 조상타입. 형변환 생략 불가
        fe2.water();
    }
}

 

 

 


🤔 InstanceOf 연산자란?

✔ 참조변수의 형변환 가능 여부 확인에 사용. 가능하면 true 반환

✔ 형변환 전에 반드시 instanceof로 확인해야 함.

 


🤔 참조변수의 형변환 이유

참조변수(리모콘)을 변경함으로써 사용할 수 있는 멤버의 갯수를 조절하기 위해서

 

🤔 instanceof 연산자는 언제 사용할까?

참조변수를 형변환하기 전에 형변환 가능여부를 확인할 때 사용한다.

 

 


🤔 다형성은?

✔ Tv t = new SmartTv();

✔ 참조변수의 형변환 - 리모컨 변경

(형변환 : 사용가능한 멤버 갯수 조절)

✔ instanceof 연산자

(형변환 가능 여부 확인)

 

🤔 다형성의 장점은?

✔ 다형적 매개변수

✔ 하나의 배열로 여러 종류의 객체를 다룰 수 있음.

 

 

🤔 매개변수의 다형성이란?

✔ 참조형 매개변수는 메서드 호출 시, 자신과 같은 타입 또는 자손타입의 인스턴스를 넘겨줄 수 있다.

 

 

다음의 실행결과를 예측해보라.

class Product {
    int price; // 제품의 가격
    int bonusPoint; // 제품구매 시 제공하는 보너스

    Product(int price) {
        this.price = price;
        bonusPoint = (int) (price / 10.0); // 보너스 점수는 제품가격의 10%
    }
}

class Tv1 extends Product {
    Tv1() {
        // 좡클래스의 생성자 Product(int price)를 호출한다.
        super(100); // Tv의 가격을 100만원으로 한다.
    }

    // Object클래스의 toString()을 오버라이딩한다.
    public String toString() {
        return "Tv";
    }
}

class Computer extends Product {
    Computer() {
        super(200);
    }

    public String toString() {
        return "Computer";
    }
}

class Buyer { // 고객, 물건을 사는 사람
    int money = 1000; // 소유금액
    int bonusPoint = 0; // 보너스 점수

    void buy(Product p) {
        if (money < p.price) {
            System.out.println("잔액이 부족하여 물건을 살 수 없습니다.");
            return;
        }

        money -= p.price; // 가진 돈에서 구입한 제품의 가격을 뺀다.
        bonusPoint += p.bonusPoint; // 제품의 보너스 점수를 추가한다.
        System.out.println(p + "을/를 구입하셨습니다.");
    }
}

class T2 {
    public static void main(String[] args) {
        Buyer b = new Buyer();

        b.buy(new Tv1());
        b.buy(new Computer());

        System.out.println("현재 남은 돈은 " + b.money + "만원입니다.");
        System.out.println("현재 보너스 점수는" + b.bonusPoint + "점입니다.");
    }
}

 

실행결과

Tv을/를 구입하셨습니다.
Computer을/를 구입하셨습니다.
현재 남은 돈은 700만원입니다.
현재 보너스 점수는30점입니다.

 

 

 

🤔 여러 종류의 객체를 배열로 다루기

✔ 조상타입의 배열에 자손들의 객체를 담을 수 있다.

 

Product p1=new Tv();
Product p1=new Computer();
Product p1=new Audio();


Product p[]=new Product[3];
p[0]=new Tv();
p[0]=new Computer();
p[0]=new Audio();

 

그림으로 그려보면 다음과 같다.

 

 

 Product[] cart = new Product[10]; // 구입한 물건을 담을 배열

다음과 같이 여러 종류의 객체를 배열로 다룰 수 있다.

 

 

class Product {
    int price; // 제품의 가격
    int bonusPoint; // 제품구매 시 제공하는 보너스

    Product(int price) {
        this.price = price;
        bonusPoint = (int) (price / 10.0); // 보너스 점수는 제품가격의 10%
    }
}

class Tv1 extends Product {
    Tv1() {
        // 좡클래스의 생성자 Product(int price)를 호출한다.
        super(100); // Tv의 가격을 100만원으로 한다.
    }

    // Object클래스의 toString()을 오버라이딩한다.
    public String toString() {
        return "Tv";
    }
}

class Computer extends Product {
    Computer() {
        super(200);
    }

    public String toString() {
        return "Computer";
    }
}

class Audio extends Product {
    Audio() {
        super(50);
    }

    public String toString() {
        return "Audio";
    }
}

class Buyer { // 고객, 물건을 사는 사람
    int money = 1000; // 소유금액
    int bonusPoint = 0; // 보너스 점수
    Product[] cart = new Product[10]; // 구입한 제품을 저장하기 위한 배열
    int i = 0; // Product 배열에 사용될 카운터

    void buy(Product p) {
        if (money < p.price) {
            System.out.println("잔액이 부족하여 물건을 살 수 없습니다.");
            return;
        }

        money -= p.price; // 가진 돈에서 구입한 제품의 가격을 뺀다.
        bonusPoint += p.bonusPoint; // 제품의 보너스 점수를 추가한다.
        cart[i++] = p; // 제품을 Product[] cart에 저장한다.
        System.out.println(p + "을/를 구입하셨습니다.");
    }

    void summary() { // 구매한 물품에 대한 정보를 요약해서 보여 준다.
        int sum = 0; // 구입한 물품의 가격 합계
        String itemList = ""; // 구입한 물품목록

        // 반복문을 이용해서 구입한 물품의 총 가격과 목록을 만든다.
        for(int i=0; i<cart.length; i++) {
            if(cart[i]==null) break;
            sum += cart[i].price;
            itemList += cart[i] + ", ";
        }
        System.out.println("구입하신 물품의 총금액은 " + sum + "만원입니다.");
        System.out.println("구입하신 제품은 " + itemList + "입니다.");
    }
}

class T2 {
    public static void main(String[] args) {
        Buyer b = new Buyer();

        b.buy(new Tv1());
        b.buy(new Computer());
        b.buy(new Audio());
        b.summary();
    }
}

실행결과

Computer을/를 구입하셨습니다.
Audio을/를 구입하셨습니다.
구입하신 물품의 총금액은 350만원입니다.
구입하신 제품은 Tv, Computer, Audio, 입니다.

 

 


기초부터 다시 하기로 마음먹길 진짜 잘한 것 같다.

되돌아 가는 것 같기도 했고,

뒤쳐지는 것 같기도 해서 많이 불안했지만

확실히 기초를 하면서 공부에 대한 감과 이해도가 훨씬 높아졌다.

 

무엇보다 공부에 대한 흥미도 다시 되찾을 수 있게 되었다.

 

더 열심히 공부하자. 📙

반응형