본문 바로가기

coding/Java

[Java] 메소드 오버로딩과 오버라이딩, Overloading vs Overriding

메소드 오버로딩 vs 메소드 오버라이딩

  • 메소드 오버로딩 : 이름이 같지만, 매개변수의 타입이나 개수가 서로 다른 여러 개의 메소드를 중복 작성하는 것
  • 메소드 오버라이딩 : 슈퍼 클래스와 서브 클래스의 메소드 사이에 발생하는 관계로서, 슈퍼 클래스에 선언된 메소드와 같은 이름, 같은 리턴 타입, 같은 매개 변수 리스트를 갖는 메소드를 서브 클래스에 재작성 하는 것

이름이 비슷해서 헷갈리기 쉽지만 엄연히 다른 개념이다. 

 

 

1. 메소드 오버로딩 (Overloading)

다음 사례를 보면서 이해해보자.

 

import java.util.*;

class MethodOverloading {
	protected String name;
	protected int age;
	
	public MethodOverloading(String name) {
		this.name = name;
		System.out.println("이름: " + name);
	}
	public MethodOverloading(String name, int age) {
		this.name = name;
		this.age = age;
		System.out.println("이름: " + name + " 나이: " + age);
	}
}

public class FinalTermTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MethodOverloading a1 = new MethodOverloading("heeya");
		MethodOverloading a2 = new MethodOverloading("heeya", 24);
	}

}

 

결과창을 보면 인스턴스 a1과 a2가 서로 다른 생성자를 불러온다는 것을 알 수 있다. 메소드 이름이 동일하지만 매개변수 개수가 서로 다르므로 두 메소드가 한 클래스에 공존 가능하다. 메소드 이름과 매개변수 개수, 타입이 모두 같으면 자바 컴파일러가 오류를 발생시킨다. 리턴 타입은 상관없다. 

 

 

 

1. 메소드 오버라이딩 (Overriding)

  메소드 오버라이딩은 상속의 개념을 알아야한다. 객체 지향에서 상속(Inheritance)은 부모 클래스에 만들어진 필드와 메소드를 자식 클래스가 물려받는 것이다. 말로 설명하기 어렵지만, 상속 선언만 하면 자식 클래스는 부모 클래스에서 만들어진 필드와 메소드를 따로 만들지 않아도 만든 것과 같은 효과를 얻을 수 있다.

 

Human 클래스의 자식 클래스들은 말하기, 먹기, 자기 3개의 메소드를 상속받을 수 있다.

 

 

import java.util.*;

class MethodOverriding {
	protected String name;
	protected int age;
	
	public MethodOverriding() {
		this.name = "heeya";
		this.age = 24;
	}
	public void intro() {
		System.out.println("이름은 " + name + ", 나이는 " + age);
	}
}

class Example1 extends MethodOverriding {
	public Example1() {}
	
	public void intro() {
		System.out.println("짜잔~ 내용이 바뀌었습니다!");
	}
}

class Example2 extends MethodOverriding {
	public Example2() {}
	
	public void intro() {
		super.intro(); //인스턴스 내부에서 super을 이용해 슈퍼 클래스의 동일 메소드 호출 가능
		System.out.println("짜잔~ 이번엔 뭐가 붙었습니다!");
	}
}
public class FinalTermTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MethodOverriding a1 = new MethodOverriding();
		Example1 a2 = new Example1();
		Example2 a3 = new Example2();
		MethodOverriding a4 = new Example1(); //업캐스팅
		a1.intro();
		System.out.println("--------------");
		a2.intro();
		System.out.println("--------------");
		a3.intro();
		System.out.println("--------------");
		a4.intro();
	}
}

 

a1, a2, a3까지는 쉽게 이해할 수 있다. 레퍼런스 a4는 MethodOverriding 타입이다. 즉, 참조변수가 슈퍼 클래스인 것이다. 마지막 출력 결과를 보면 알겠지만 intro()를 Eample1에서 오버라이딩한 값이 나온다. a4.intro()를 컴파일 할 때, 컴파일러는 MethodOverriding 클래스에 into() 멤버가 있는지 확인하고 호출한다. 하지만 a4.intro()의 실행 시, a4가 가리키는 객체에는 Example1의 intro()가 존재하기 때문에 오버라이딩 된 메소드가 호출된다. 이 과정을 동적 바인딩이라고 부른다.