다형성 [ 정리]

다형성(polymorphism)이란?

다형성(polymorphism)이란 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미한다.

자바에서는 이러한 다형성을 부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하여 구현하고 있다.

다형성은 상속, 추상화와 더불어 객체 지향 프로그래밍을 구성하는 중요한 특징 중 하나이다.

참조 변수의 다형성
자바에서는 다형성을 위해 부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하고 있습니다.

이때 참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 같거나 적어야 참조할 수 있다.

위에서 언급된 인스턴스란? 일반적으로 실행 중인 임의의 프로세스, 클래스의 현재 생성된 오브젝트를 가리키고, 시스템 자원의 접근에 할당된 물리 메모리 일부를 가리킨다.
"클래스로 인해 생성된 하나의 객체"라고 보면 된다.

class Parent { ... }
class Child extends Parent { ... }
...
Parent pa = new Parent(); // 허용
Child ch = new Child();   // 허용
Parent pc = new Child();  // 허용
Child cp = new Parent();  // 오류 발생.

특정 타입의 참조 변수로는 당연히 같은 타입의 인스턴스를 참조할 수 있다.

  • 참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수와 같기 때문이다.

그리고 부모 클래스 타입의 참조 변수로도 자식 클래스 타입의 인스턴스를 참조할 수 있다.

  • 참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 적기 때문이다.

하지만 반대의 경우인 자식 클래스 타입의 참조 변수로는 부모 클래스 타입의 인스턴스를 참조할 수 없다.

  • 참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 많기 때문이다.

참조 변수의 타입 변환
자바에서는 참조 변수도 다음과 같은 조건에 따라 타입 변환을 할 수 있다.

  1. 서로 상속 관계에 있는 클래스 사이에만 타입 변환을 할 수 있다.

  2. 자식 클래스 타입에서 부모 클래스 타입으로의 타입 변환은 생략할 수 있다.

  3. 하지만 부모 클래스 타입에서 자식 클래스 타입으로의 타입 변환은 반드시 명시해야 한다.

참조 변수의 타입 변환도 기본 타입의 타입 변환과 마찬가지로 타입 캐스트 연산자(())를 사용합니다.

class Parent { ... }
class Child extends Parent { ... }
class Brother extends Parent { ... }
...
Parent pa01 = null;
Child ch = new Child();
Parent pa02 = new Parent();
Brother br = null;

pa01 = ch;          // pa01 = (Parent)ch; 와 같으며, 타입 변환을 생략할 수 있음.
br = (Brother)pa02; // 타입 변환을 생략할 수 없음.
br = (Brother)ch;   // 직접적인 상속 관계가 아니므로, 오류 발생.

자바에서 다형성을 지원하는 방법으로 메서드 오버로딩과 오버라이딩

오버로딩 & 오버라이딩

서로의 개념은 차이가 있지만, 비슷한 이름때문에 혼동이 잦다.

오버로딩(Overloading) : 같은 이름의 메서드 여러개를 가지면서 매개변수의 유형과 개수가 다르도록 하는 기술

  • 오버로딩은 메서드 오버로딩과 생성자 오버로딩이 있다.(같은 개념)
    class OverloadingTest{
       //이름이 cat인 메서드
       void cat(){
           System.out.println("매개변수 없음");
       }
       
       //매개변수 int형이 2개인 cat 메서드
       void cat(int a, int b){
           System.out.println("매개변수 :"+a+", "+b);
       }
       
       //매개변수 String형이 한 개인 cat 메서드
       void cat(String c){
           System.out.println("매개변수 : "+ c);
       }   
    }
    public class OverTest {
       public static void main(String[] args) {
         
           //OverloadingTest 객체 생성
           OverloadingTest ot = new OverloadingTest(); 
           
           //매개변수가 없는 cat() 호출
           ot.cat();        
           
           //매개변수가 int형 두개인 cat() 호출
           ot.cat(20, 80);       
           
           //매개변수가 String 한개인 cat() 호출
           ot.cat("오버로딩 예제입니다.");   
       }
    }

**오버라이딩(Overriding)** : **상위 클래스가 가지고 있는 메서드를 하위 클래스가 재정의해서 사용**
-  상위 클래스가 가지고 있는 멤버변수가 하위 클래스로 상속되는 것처럼 상위 클래스가 가지고 있는 메서드도 하위 클래스로 상속되어 하위 클래스에 사용할 수 있다. 
또한, 하위 클래스에서 메서드를 재정의해서도 사용할 수 있다.

즉, 메서드의 이름이 서로 같고, 매개변수가 같고, 반환형이 같을 경우에 상속받은 메서드를 덮어쓴다고 생각하하면된다. '부모클래스의 메서드는 무시하고, 자식 클래스의 메서드 기능을 사용하겠다'와 같다.

class Woman{ //부모클래스
public String name;
public int age;

//info 메서드
public void info(){
    System.out.println("여자의 이름은 "+name+", 나이는 "+age+"살입니다.");
}

}

class Job extends Woman{ //Woman클래스(부모클래스)를 상속받음 :

String job;

public void info() {//부모(Woman)클래스에 있는 info()메서드를 재정의
    super.info();
    System.out.println("여자의 직업은 "+job+"입니다.");
}

}

public class OverTest {

public static void main(String[] args) {
    
    //Job 객체 생성
    Job job = new Job();
    
    //변수 설정
    job.name = "유리";
    job.age = 30;
    job.job = "프로그래머";
    
    //호출
    job.info();   
}

}


오버로딩과 오버라이딩의 성립조건
![](https://media.vlpt.us/images/mon99745/post/307da4e3-430e-40ac-898a-0790a21de93d/image.png)


**References (참고 자료)**
> - http://www.tcpschool.com/java/java_polymorphism_concept
- https://private.tistory.com/25

좋은 웹페이지 즐겨찾기