페이지

2015. 1. 12.

[JAVA] Day6.다형성(polymorphism)

5. 다형성(polymorphism)


 - 조상의 참조변수로 자손의 객체를 사용하는 것


다형성이 가장 중요함!

상속관계가 맺어졌을떄만

조상에게만 해당

조상이 자손의 클래스를 참조...







A가 조상이고 B가 자손인 경우
A a = new B(); << 가능, B()에는 조상, 자식 다있음
B b = new A(); << 불가능, A()에는 조상꺼 밖에 없음


따라서

Object obj = new A(); 당연히 가능!! 오브젝트는 모든 클래스 가능!
(리턴타입이 무엇인지 잘모르고 예측이 어려울때 모든 자바 클래스의 조상인 Object로 받아 사용한다. 또는 대입되는, 리턴되는 타입이 무엇인지 모를때 모든 것을 받을 수 있는 Object 클래스를 사용한다. )

ex) int add(Object obj) {~~}  << 모든 타입을 받겠다는 의미


즉, 다형성은 오버라이딩된 자손 클래스의 메서드를 쓰기위한 방법!!








5.1 다형성이란?


 - 여러 가지 형태를 가질 수 있는 능력
 - 하나의 참조변수로 여러 타입의 갹체를 참조할 수 있다는 것
 - 즉, 조상타입의 참조변수로 자손타입의 객체를 다룰 수 있다는 것이 다형성.
 - 조상타입의 참조변수로 자손타입의 인스턴스를 참조할수 있지만, 반대로 자손타입의 참조변수로 조상타입의 인스턴스를 참조할 수는 없다.
    A가 조상이고 B가 자손인 경우
    A a = new B(); << 가능, B()에는 조상, 자식 다있음
    B b = new A(); << 불가능, A()에는 조상꺼 밖에 없음


class A
{
    int x = 10;
    void add()
    {
        System.out.println("자손");
    }
}
class B extends A
{
    int x = 20;
    void add()
    {
        System.out.println("자손");
    }
    void test(){}
}
class Test
{
    public static void main(String[] args)
    {
        A a = new B();
        a.add();
        //조상 클래스가 자식 클래스의 오버라이딩된 메서드를 사용하기 위함
        //자손의 test()는 사용불가능
    }
}








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

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

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

    public String toString() {    // Object클래스의 toString()을 오버라이딩한다.
        return "Tv";                   //그냥 참조변수만 호출하면 toString이 호출된다!!
    }
}

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

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

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

    void buy(Product p) {    //다형성 : 자손인 컴퓨터와 TV가 들어갈 예정
        if(money < p.price) {
            System.out.println("잔액이 부족하여 물건을 살수 없습니다.");
            return;
        }

        money -= p.price;            // 가진 돈에서 구입한 제품의 가격을 뺀다.
        bonusPoint += p.bonusPoint;    // 제품의 보너스 점수를 추가한다.
        System.out.println(p + "을/를 구입하셨습니다.");
        //그냥 참조변수만 호출하면 toString이 호출된다!!
    }
}

class PolyArgumentTest{
    public static void main(String args[]) {
        Buyer b = new Buyer();
        Tv tv = new Tv();
        Computer com = new Computer();

        b.buy(tv);
        b.buy(com);

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





















5.2 참조변수의 형변환

 - 서로 상속관계에 있는 타입간의 형변환만 가능하다.
 - 자손 타입에서 조상타입으로 형변환하는 경우, 형변환 생략가능
    자손타입->조상타입(up-casting) : 형변환 생략 가능
    조상타입->자손타입(down-casting) : 형변환 생략 불가
    약간 비슷한 개념으로 보면 double형 5.7을 int 에 삽입시 5는 사용가능하고 0.7은 버려지는 것과 비슷


class CastingTest1
{
    public static void main(String[] args)
    {
        Car car = null;
        Car car2 = null;
        FireEngine fe = new FireEngine();
        FireEngine fe2 = null;

        fe.water();
        car = fe;        // car = (Car)fe1;에서 형변환이 생략된 형태이다.
//        car.water();    // 컴파일 에러!!! Car타입의 참조변수로는 water()를 참조할수 없당.
        fe2 = (FireEngine)car;    // 자손타입 <- 조상타입
                                // 의미상 조상이 자손보다 더 큰 데이터 타입이라고 볼수있다.(크기로 보면 자식이 더 크지만..)
        fe2.water();
        // 주로 Object 클래스에 넘겨서 한다..

    }
}
class Car
{
    String color;
    int door;
    void drive()
    {
        System.out.println("drive");
    }
    void stop()
    {
        System.out.println("stop");
    }
}
class FireEngine extends Car
{
    void water()
    {
        System.out.println("water");
    }
}


5.3 instanceof 연산자


 - 참조변수가 참조하는 인스턴스의 실제 타입을 체크하는데 사용
 - 이항연산자이며 피연산자는 참조형 변수와 타입, 논리형을 리턴함
 - instanceof의 연산 결과 true이면, 해당 타입으로 형변환이 가능하다.


5.4 참조변수와 인스턴스변수의 연결


 - 맴버변수가 중복정의된 경우, 참조변수의 타입에 따라 연결되는 맴버변수가 달라진다.(참조변수타입에 영향받음)
 - 메서드가 중복 적의된 경우, 참조변수의 타입에 관계없이 항상 실제 인스턴스의 타입에 정의된 메서드가 호출된다.(참조변수타입에 영향받지 않음)


5.5 매개변수의 다형성


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