객체지향에서 다형성이라고 한다면 오버라이딩(overriding)과 오버로딩(overloadiong)을 들 수 있습니다.
오버라이딩 : 상위 클래스가 가지고 있는 메서드를 하위 클래스가 재정의해서 사용하는것을 의미
(메서드의 이름은 물론 파라메터의 개수나 타입도 동일해댜 하며, 주로 상위 클래스의 동작을 상속 받은 하위 클래스에서 변경하기 위해 사용됩니다.)
오버로딩 : 메서드의 이름은 같고 매개변수의 유형과 개수가 다르도록 하는 것
(리턴값만을 다르게 갖는 오버로딩은 작성 할 수 없습니다.)
오버라이딩과 오버로딩은 코드로 살펴보겠습니다.
package jv.part03
public class Animal{
public String name;
public void showName(){
System.out.println("안녕 나는 " + name +"이야");
}
}
[그림 1.1] Animal.java
package jv.part03
public class Mouse extends Animal{
public String habitat;
public void showHabitat(){
System.out.println(name + "는 " + habitat +"에 살아");
}
//오버라이딩 - 재정의 : 상위클래스의 메서드와 같은 메서드 이름, 같은 인자 리스트
public void showName(){
System.out.println("응 안 알려줄거야");
}
//오버로딩 중복정의 : 같은 메서드 이름, 다른 인자 리스트
public void showName(String yourName){
System.out.println("안녕 "+yourName+"아 나는 "+name+"이야");
}
}
[그림 1.2] Mouse.java
package jv.part03
public class Driver{
public static void main(String[] args){
Mouse jerry = new Mouse();
jerry.name = "제리";
jerry.habitat = "쥐구멍";
jerry.showName();
jerry.showName("톰");
jerry.showHabitat();
Animal mickey = new Mouse();
mickey.name = "미키";
mickey.showName();
}
}
[그림 1.3] Driver.java
Driver.java를 실행한 결과는 다음과 같다.
jerry.showName()과 jerry.showName("톰")이 오버로딩에 의해 다르게 출력되는 것과 객체 참조 변수타입이 Animal인 mickey의 showName()이 Mouse객체의 showName()으로 실행되는 것을 확인 할 수 있다. 이는 메모리에 저장되는 모습을 보면 더 쉽게 이해할 수 있다.
Driver.java의 main메소드가 종료되기 직전의 메모리를 [그림 1.4]에 표현해 보았다.
[그림 1.4] Driver.java를 실행한 메모리
[그림1.4]에서 주목할 것은 Mouse 클래스가 상위 클래스인 Animal 클래스의 showName() 메서드를 오버라이딩했다는 것과 showName(yourName: String) 메서드를 오버로딩 했다는 것이다. jarry.showName()을 실행하면 Animal 객체에 있는 showName() 메서드가 Mouse 객체에 있는 showName() 메서드에 의해 재정의 되었기 때문에 재정의된 메서드가 호출된다.
jarry.showName("톰"); 을 실행하면 오버라이딩된 showName(yourName) 메서드가 호출된다.
가장 주목할 부분은 mickey의 showName() 메서드 실행 결과이다. 위에 말했듯이 Animal객체의 showName()은 Mouse객체의 showName()에 의해 가려져 있기 때문에 객체 참조 변수 타입이 Animal인 mickey 또한 재정의된 메서드를 호출하게 된다.
상위 클래스 타입의 객체 참조 변수를 사용하더라도 하위 클래스에서 오버라이딩(재정의)한 메서드가 호출된다.