다형성이란 프로그램 언어 각 요소들(상수, 변수, 식, 객체, 메소드 등)이 다양한 자료형(type)에 속하는 것이 허가되는 성질을 가리킨다.
위키피디아에서 발췌해온 내용이다.
해당 정의를 봤을 때, 쉽게 이해하기는 어려울 것이다.
필자의 상속 게시물에서 다형성이 등장했다.
코드를 통해 미리 설명하자면 다음과 같다.
public static void main(String[] args) {
final 첫째 firstBorn = new 첫째("철수");
final 둘째 secondBorn = new 둘째("영희");
final List<HwanFamily> hwanFamily = List.of(firstBorn, secondBorn);
for (HwanFamily familyMember : hwanFamily) {
familyMember.eatBreakfastWithFamily();
familyMember.eatDinnerWithFamily();
System.out.println();
}
}

위와 같이 하나의 타입에 여러 객체를 대입할 수 있는 성질이다.
다형성은 다음과 같은 장점을 가진다.
오버로딩이란 한 클래스 내에 동일한 이름을 가진 메소드가 있더라도, 매개 변수의 개수 혹은 타입이 다른 경우에 같은 이름을 사용해서 메소드를 정의할 수 있는 것을 의미한다.
오버로딩은 컴파일 시점에 함수의 인자를 바탕으로 적절한 메소드를 찾기 때문에, 이를 정적 다형성이라고도 부른다.
오버로딩의 조건
- 한 클래스 내에서 메소드 명이 동일해야 한다.
- 매개 변수의 개수 또는 타입이 달라야 한다.
- 매개변수는 같고, 리턴 타입이 다른 경우는 오버로딩이 성립되지 않는다.
(리턴 타입은 오버로딩에 영향을 주지 않는다.)
public class Main {
public int overloading(int a, int b) {
return a + b;
}
public double overloading(double a, double b) {
return a + b;
}
public String overloading(String a, String b) {
return a + b;
}
public void overloading(List<String> list) {
for (String s : list) {
System.out.println(s);
}
}
public static void main(String[] args) {
Main main = new Main();
System.out.println(main.overloading(1, 2));
System.out.println(main.overloading(1.5, 2.5));
System.out.println(main.overloading("Hello ", "World"));
main.overloading(List.of("I'm", "Seokhwan"));
}
}

예시를 살펴 보면, overloading 이라는 동일한 메서드 명을 가진다.
하지만, 매개 변수의 개수나 타입이 다름에 따라 다른 동작을 수행하는 것을 알 수 있다.
오버로딩의 대표적인 예는 println()이다.
실제로 Java에서 println() 메소드를 뜯어보면 PrintStream Class에서 매개 변수에 따라 추력할 수 있도록 여러 개의 오버로딩된 println() 메소드를 정의하고 있다.

오버라이딩이란 상속 관게에서 자식 클래스가 부모 클래스의 메소드를 재정의하는 것을 의미한다.
상속받은 메소드를 그대로 사용하거나, 자식 클래스에서 상황에 맞게 변경이 가능한 경우에 사용한다.
@Override 어노테이션은 오버라이딩을 검증하는 기능을 한다.
코드를 검색했을 때, 오버라이딩이 실제로 시행되지 않았다면 컴파일시에 오류를 출력한다.
오버라이딩은 런타임에 객체의 타입에 따라 적절한 메소드를 동적으로 호출하기 때문에, 이를 동적 다형성이라고도 부른다.
오버라이딩 조건
- 상속 관계
- 부모 클래스의 메서드와 동일한 이름, 매개 변수, 리턴 타입을 가져야 한다.
- 부모 클래스와 같거나 더 넓은 범위의 접근 제어자를 설정해야 한다.
public class Main {
static class Car {
public void sound() {
System.out.println("자동차는 부우우웅하고 달립니다.");
}
}
static class Hyundai extends Car {
@Override
public void sound() {
System.out.println("현대차: 부우우웅");
}
}
static class Kia extends Car {
@Override
public void sound() {
System.out.println("기아차: 부우우웅");
}
}
public static void main(String[] args) {
List<Car> cars = List.of(new Car(), new Hyundai(), new Kia());
for (Car car : cars) {
car.sound();
}
}
}

Hyundai, Kia 클래스는 Car 클래스의 sound()를 재정의(오버라이딩)하여 다르게 출력한다.
References
http://wiki.hash.kr/index.php/오버로딩
https://highright96.tistory.com/96