이번글은 OOP의 4가지 특징 중 3번째인
다형성이다.
다형성에 대해선 아는 것이 없었기에
공부하는데 시간이 들었지만,
다행히 이해는 된거 같다.
다형성
프로그램 언어의 다형성(多形性, 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 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도 다형성의 한 예시라고 한다.
상속 관계에 있는 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가지 규칙이 존재하는데,
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가지 특징 중 상속 외에는 잘 몰랐다.
이 기회로 제대로 공부하게 되는거 같아
정말 뜻깊은 시간이었다.
다음은 추상화이다.