1.9.6 다형성

yeonseong Jo·2023년 4월 26일
0

SEB_BE_45

목록 보기
15/47
post-thumbnail

이번글은 OOP의 4가지 특징 중 3번째인
다형성이다.
다형성에 대해선 아는 것이 없었기에
공부하는데 시간이 들었지만,
다행히 이해는 된거 같다.

Polymorphism

다형성

프로그램 언어의 다형성(多形性, polymorphism; 폴리모피즘)은 그 프로그래밍 언어의 자료형 체계의 성질을
나타내는 것으로, 프로그램 언어의 각 요소들(상수, 변수,
식, 오브젝트, 함수, 메소드 등)이 다양한 자료형(type)에
속하는 것이 허가되는 성질을 가리킨다.

출처

특징

다형성이라는 단어 자체를 잘 쓰지 않기 때문에
조금 낯설었다.
그래도 요약을 하자면 java에서 다형성은
어느 한 type의 참조 변수를 통해
여러 type의 객체를 참조할 수 있도록 만든 것을 의미한다.

예를들어

class Parent {
	public void print(){
    	System.out.println("parent");
    }
}
class Child1 extends Parent {
	public void print(){
    	System.out.println("child1");
    }
}
class Child2 extends Parent {
	public void print(){
    	System.out.println("child2");
    }
}

이렇게 부모 class 하나와
이를 상속 받는 자식 class 두개 가 있을 때,

class Main {
	public static void main(String[] args){
    	Child1 c1 = new Child1();
        Child2 c2 = new Child2();
        
        Parent c1_1 = new Child1();
        Parent c2_1 = new Child2();
        
        //Child1 c3 = new Parent(); 불가능
        //child2 c4 = new Parent(); 불가능
        
        c1.print();
        c2.print();
        c1_1.print();
        c2_1.print();
    }
}

실행 결과는

child1
child2
child1
child2

일 것이다.

이처럼 참조 변수의 type과 생성자 class의 type이 다르지만,
오류가 일어나지 않는다.

상위 class 참조변수

class Parent {
	int n = 0;
}
class Child extends Parent {
	int n = 1;
}

라 두고,

class Main {
	public static void main(String[] args){
    	Child c1 = new Child();
        Parent c2 = new Child();
        
		System.out.println(c1.n);
        System.out.println(c2.n);
    }
}

실행 결과는

1
0

이 될 것이다.
이는 상위 class를 참조 변수의 type으로 지정했을 때,
참조 변수가 사용할 수 있는 member의 개수는
상위 class의 member의 수
가 되기 때문이며,
다형성의 핵심적인 부분이다.

overridng과 overloading도 다형성의 한 예시라고 한다.

down & up casting

상속 관계에 있는 class는 type 변환이 가능하다.

class Main {
    public static void main(String[] args){
        Child c1 = new Child();
        Parent p1 = new Parent();

        Child c2 = (Child) p1; 
        // downcasting 형 변환 연산자 "(Child)" 필요
        Parent p2 =  c1;
        // upcasting 형 변환 연산자 "(Parent)" 생략 가능
    }
}

이 때 3가지 규칙이 존재하는데,

  • 서로 상속 관계여야 한다.
  • 하위 -> 상위 class의 upcasting은
    형 변환 연산자 생략이 가능하다.
  • 상위 -> 하위 class의 downcasting은
    형 변환 연산자를 반드시 명시해야 한다.

instanceof

instanceof 연산자를 통해
형 변환이 가능한지 여부를 확인할 수 있다.

class Main {
    public static void main(String[] args){
        Child c1 = new Child();
        Parent p1 = new Parent();

        System.out.println(p1 instanceof Object);
        System.out.println(p1 instanceof Parent);
        System.out.println(p1 instanceof Child);
        System.out.println(c1 instanceof Parent);
    }
}

실행 결과는

ture
true
false
true

그래서 왜 쓰는데?

다형성에 대해 학습을 했어도,
아직 왜 쓰는지에 대해 잘 이해가 안갔었다.
다행히 수업에서 예를 들어주어 설명을 했어서
이를 요약해 본다.

class Parent{
	int n;
    public Parent(int n){
    	this.n = n;
    }
}
class Child1 extends Parent {};
class Child2 extends Parent {};
class Print{
	void printChilds(Child1 c){
    	System.out.println(c.n);
    }
    void printChilds(Child2 c){
    	System.out.println(c.n);
    }
}

이러한 상황일 때,
Parent class 상속받는 Child가 늘어날 때마다
Print class에서 overloading을 사용한 method가 늘어날 것이다.
이 때 객체의 다향성을 활용하여 Print class를 수정한다면,

class Print{
	void printChilds(Parent p){
    	System.out.println(p.n);
    }
}

printChilds method를 실행할 때,
다형성으로 인해 Parent class를
상속받는 class를 parameter로 넣더라도,
Parent의 type을 포함하기 때문에
위와 같이 수정할 수 있다.

이를 통해 중복되는 코드를 줄일 수 있고,
코드 작성이 편리해 진다.

회고

솔직히 django로 개발만 주구장창 했을 때,
이론에 관해선 하나도 본 적이 없기 때문에
OOP 4가지 특징 중 상속 외에는 잘 몰랐다.
이 기회로 제대로 공부하게 되는거 같아
정말 뜻깊은 시간이었다.
다음은 추상화이다.

profile
뒤(back)끝(end)있는 개발자

0개의 댓글