다형성

Heidi·2023년 6월 14일
0

다형성은 동일한 코드로 다양한 타입의 객체를 처리하는 기법을 의미함. 넓은 의미에서는 메소드 오버로딩, 오버라이딩, 제네릭 프로그래밍도 다형성에 포함된다.

업캐스팅

예시

class Shape {
    protected int x, y;
    public void draw() {
        System.out.println("Shape Draw");
    }
}

class Rectangle extends Shape {
    private int width, height;
    public void draw() {
        System.out.println("Rectangle Draw");
    }
}

public class PolyMorphism {
    public static void main(String[] args) {
        Shape s1, s2;

        s1 = new Shape();        //1
        s2 = new Rectangle();    //2
    }    
}
  1. Rectangle 타입의 객체를 Shape 타입의 변수로 참조하는 문장은 얼핏 오류로 보인다. 그러나 자식 클래스 객체는 부모 클래스 객체를 포함하고 있기 때문에 위의 문장은 적법하다. 즉 부모 클래스 변수(s1, s2)로 자식 클래스 객체(Rectangle())를 참조할 수 있다. 이것을 업캐스팅(upcasting, 상형 형변환)이라고 한다.

그렇다면 2와 같이 부모 클래스 변수로 자식 클래스 객체를 참조하였을 경우, s2를 통하여 자식 클래스의 모든 필드와 메소드를 사용할 수 있을까? 그렇지는 않다. 자식 클래스 중에서 부모 클래스로부터 상속받은 부분만을 s2를 통해서 사용할 수 있고, 나머지는 사용하지 못한다.

=> 자식 클래스 안에 부모 클래스가 포함되기 때문에(=자식 클래스가 더 큰 범위이기 때문에), 부모 클래스 변수로 자식 클래스 객체를 참조할 수는 있지만, 부모 클래스 변수는 부모 클래스에 있는 부분만을 사용할 수 있음. 자식 클래스에서 추가된 부분은 사용하지 못함.

위에서 조금 더 변형된 코드를 살펴보자.


public class PolyMorphism {
    public static void main(String[] args) {
        Shape s = new Rectangle();
        Rectangle r = new Rectangle();

        s.x = 0;    //1
        s.y = 0;    //2

        s.width = 100;   //3
        s.height = 100;  //4
    }    
    
    

1, 2 => s가 Shape의 변수이기 때문에 Shape 클래스의 필드(int x, int y)와 메소드에 접근할 수 있음. 오류 나지 않음

3,4 => 컴파일 오류 발생. s는 Shape의 변수이기 때문에 Rectangle 클래스의 필드(width, height)와 메소드에 접근할 수 없다.

그렇지만 r을 통해서는 모든 필드를 전부 사용할 수 있다. r이 자식 클래스의 객체고, 자식 클래스는 부모 클래스를 포함하고 있는, 자식 클래스가 더 큰 개념이기 때문임. 부모 클래스는 자식 클래스가 무엇을 추가하였는지 알 수 있는 방법이 없기 때문.

기억해야 할 것은 어떤 메소드나 필드를 사용할 수 있는지는 변수의 타입(부모 클래스 변수인지, 자식 클래스 변수인지)에 의하여 결정된다는 것

다운캐스팅

업캐스팅: 자식 객체를 부모 참조 변수로 참조하는 것. 묵시적으로 수행될 수 있다.
다운캐스팅: 부모 객체를 자식 참조변수로 참조하는 것이다. 명시적으로 하여야한다.

class Parent {
    void print() {
        System.out.println("Parent 메소드 호출");
    }
}

class Child extends Parent {
    void print() {
        System.out.println("Child 메소드 호출");
    }
}

public class Casting {
    public static void main(String[] args) {
        Parent p = new Child();
        p.print();

        //Child c = new Parent();

        Child c = (Child)p;
        c.print();
    }
}

    
  1. Parent p = new Child();
    p.print();
    => 업캐스팅. 자식 객체(Child)를 부모 객체(Parent)로 형변환. p.print(); - 자식 메소드 호출.

  2. //Child c = new Parent();
    => 자식 클래스 변수(c)를 부모 객체(Parent)로 형변환하려고 했으나, 다운캐스팅은 묵시적으로 불가능하기 때문에 오류.

  3. Child c = (Child)p;
    c.print();
    => 다운캐스팅. 부모 객체(p)를 자식 객체(Child)로 형변환. 메소드 오버라이딩으로 부모 객체 무효화돼서, 자식 객체의 print() 호출.

0개의 댓글

관련 채용 정보