Inor

[JAVA] Overloading과 Overriding 본문

Computer Engineering/Java

[JAVA] Overloading과 Overriding

Inor 2017. 7. 17. 16:24

자바에서는 OOP의 다형성이라는 특징을 지원하기 위해서 Overloading과 Overriding이라는 방법을 지원 합니다. 비슷한듯 완전 다른 두 방법을 한국어로 풀어서 써 보면 메서드의 중복(Overloading)과 메서드의 재정의(Overriding)라고 할 수 있습니다. 간단히 설명하면 아래와 같이 두 개념을 정의할 수 있습니다.


  • Overloading : 같은 클래스에서 같은 이름의 메서드를 여러개 만들어서 사용할 수 있도록 해주는 방법
  • Overriding : 부모 클래스를 상속 받은 자식 클래스에서 부모 클래스의 메서드를 자식 클래스에 맞게 재정의 하는 방법


Overloading

 오버로딩을 설명하기 전에 아래의 예제 코드를 확인 하겠습니다. 아래의 코드는 메소드 오버로딩의 필요성을 어필하기 위한 코드 입니다.

class Mcdonald{
	
	public void order(int price){
		System.out.println("제출 금액 : " + price);
	}
	
	public void orderPoint(int price, int point){
		System.out.println("제출 금액 : " + price);
		System.out.println("사용 포인트 : " + point);
	}
	
}

 위의 코드에대한 설명을 하겠습니다. Mcdonald 클래스에서 처음에는 order 메서드를 통해서만 주문을 받았습니다. 그러나 고객이 많아지고 요구사항이 늘어나면서 포인트를 사용해서 할인을 받을 수 있는 시스템을 만들어야 했습니다. 그리고 그 결과로 포인트를 사용해서 주문을 해야될 경우에는 orderPoint 메서드를 사용해서 주문을 하도록 코드를 수정 했습니다.
 위의 코드의 문제점은 사용자의 입장에서는 느끼지 못할 수 있습니다. 하지만 개발자의 관점에서 본다면 프로그램이 점점 커질수록 다른 방식의 주문 방법이 생길 수 있는데 그때마다 메서드의 이름을 다시 정의하는 상황이 발생할 수 있습니다. 이런 문제점을 해결 할 수 있는 방법 중 하나가 메서드의 오버로딩 입니다. 위의 코드를 메서드 오버로딩을 통해서 해결 해보도록 하겠습니다.

class Mcdonald{
	
	public void order(int price){
		System.out.println("제출 금액 : " + price);
	}
	
	public void order(int price, int point){
		System.out.println("제출 금액 : " + price);
		System.out.println("사용 포인트 : " + point);
	}
	
	public void order(int price, boolean isCard){
		System.out.println("제출 금액 : " + price);
		System.out.println("카드 사용 : " + isCard);
	}
	
	public void order(int price, int point, boolean isCard){
		System.out.println("제출 금액 : " + price);
		System.out.println("사용 포인트 : " + point);
		System.out.println("카드 사용 : " + isCard);
	}
	
}

 위의 코드는 메서드 오버로딩을 통해서 order라는 이름의 메서드를 중복해서 여러개 선언한 코드 입니다. 이런 방법으로 같은 이름의 메서드이지만 매개변수에 따라서 다른 형태로 사용할 수 있게 됩니다. 
 오버로딩이란 같은 클래스에서 함수의 이름을 중복해서 사용하는 방법 입니다. 오버로딩이 성립하도록 하려면 몇 가지 약속을 지켜야 합니다. 메서드의 이름은 같아야하고 매개변수의 타입이나 개수가 달라야 합니다. 참고로 리턴 타입이 다르지만 매개변수가 같은 경우는 오버로딩이 성립되지 않습니다.



Overriding

 오버로딩의 경우에는 하나의 클래스에서 사용 가능한 것이고 오버라이딩의 경우에는 상속 관계에서 사용 가능한 방법 입니다. 오버라이딩은 메서드의 재정의로서 부모 클래스의 메서드를 같은 리턴 타입, 이름, 매개변수를 갖고 있는 메서드로 자식 클래스에서 재정의 하는 것 입니다. 부모 클래스를 상속 받은 자식 클래스의 객체는 부모 클래스의 메서드를 사용 할 수 있습니다. 그러나 부모 클래스의 메서드를 주어진 그대로 사용해야 한다면 제약이 생길 수 있습니다. 그것을 해결해줄 수 있는 방법이 오버라이딩 입니다. 예제 코드를 확인하면서 조금 더 자세히 알아보도록 하겠습니다.


class Car{
	public void accelate(){
		System.out.println("일반 엔진 사용");
	}
}
 
class RacingCar extends Car{
	public void accelate(){
		System.out.println("레이싱카 전용 엔진 사용");
		
	}
}

public class Overriding {
	public static void main(String[] args) {
		Car myCar = new RacingCar();
		myCar.accelate();
	}
}

 위 코드의 결과는 "레이싱카 전용 엔진 사용" 입니다. 이 예제에서 주목해야 하는 클래스는 Car와 RacingCar 입니다. 각각의 클래스는 accelate라는 메서드를 갖고 있고 RacingCar에서는 Car의 accelate 메서드를 재정의 했습니다. 그렇게 생성된 RacingCar의 객체를 통해서 accelate 메서드를 호출하면 Car의 accelate가 호출 되는 것이 아니라 RacingCar의 accelate가 호출이 됩니다. 

 상속의 상황에서 부모 클래스는 자식 클래스의 기본적인 동작 방법을 정의한 것이라고 할 수 있습니다. 특수한 상황(오버라이딩 된 메서드)은 기본적인 상황(부모 클래스의 메서드)보다 더 높은 우선순위를 갖고 있습니다. 그렇기 때문에 accelate 메서드를 호출 했을때 부모 클래스의 메서드가 호출 되는 것이 아니라 자식 클래스의 메서드가 호출 되는 것 입니다.

 오버라이딩의 기본적인 규칙은 리턴 타입, 메서드 이름, 매개변수가 모두 동일 해야지 허용 됩니다. 그러나 한 가지 제약 사항이 있는데 그것은 "static 메서드는 오버라이딩을 허용하지 않는다." 입니다. 사실 클래스 메서드에대한 오버라이딩은 하이딩(Hiding)이라고 부르는데 추후에 조금 더 자세히 알아보도록 하겠습니다.




참조


Comments