1. 오버라이딩(overriding)
: 오버라이딩은 재정의, 새롭게 정의한다는 뜻으로 상속과 아주 밀접한 관련에 있는 개념이다.
부모 클래스가 가진 기본적인 기능에 자식 클래스의 기능을 필요에 따라 변경해서 재사용하는 것을 말한다.
상속에 대해 아주 간단하게 말하자면, 상속은 부모 클래스가 있고 자식클래스가 있을 때, 부모 클래스에 있는 특정 변수나 메소드를 자식 클래스가 그대로 사용하면서 동시에 자식 클래스에 어떤 특정한 메소드나 변수를 추가해서 부모 클래스가 가진 기능보다 더 많은 기능을 제공한다는 개념이다.
예제로 확인해보자 !
package example1;
class Calculator(){ // Calculator 클래스 정의
int left, right;
public void setOperands(int left, int right){
this.left = left;
this.right = right;
}
public void sum(){
System.out.println(this.left+this.right);
}
public void avg(){
System.out.println((this.left+this.right)/2);
}
}
class SubstractionableCalculator extends Calculator {
// Calculator 클래스를 상속하는 SubstractionableCalculator 클래스
public void sum(){ // 부모가 이미 갖고 있는 메소드 sum()을 재정의
System.out.println("실행 결과는 " +(this.left+this.right)+"입니다.");
}
public void substract(){
System.out.prinln(this.left+this.right);
}
}
public class CalculatorDemo{
public static void main(String[] args){
SubstractionableCalculator c1 = new SubstractionableCalculator();
c1.setOperands(10,20);
c1.sum();
c1.avg();
c1.substract();
}
}
-> c1.sum()을 실행했을때 실제 호출되는 sum()메소드가 부모 Calculator클래스의 멤버인지 자식 SubtractionableCalculator 클래스의 멤버인지 알아보자.
위의 코드를 컴파일 시키면, sum()메소드 부분에서 "실행결과는 30입니다"가 출력된다.
즉, 자식 클래스의 sum()메소드가 실행되었다 !
부모 클래스에서 갖고 있는 메소드를 자식 클래스에서 재정의하고, 이 메소드를 호출하면 부모 클래스가 가진 메소드는 무시되고, 자식 클래스에서 재정의된 메소드가 호출된다.
이게 바로 메소드 오버라이딩이다.
오버라이딩이 무엇인지 알았으니, 오버라이딩을 사용할때의 제약조건에 대해 공부해보자.
기본 코드는 위와 동일하다.
package example1;
class Calculaotr{
int left, right;
public void setOperands(int left, int right){
this.right = right;
this.left = left;
}
public void sum(){
System.out.println(this.right+this.left);
}
public void avg(){ // 반환값 void
System.out.println((this.right+this.left) / 2);
}
}
class SubstractionableCalculator extends Calculator{
public void sum(){
System.out.println("실행 결과는 "+(this.left+this.right)+"입니다.");
}
public int avg(){ // 반환값 int
return (this.left + this.right)/2;
}
public void substract(){
System.out.println(this.left-this.right);
}
}
public class CalculatorDemo{
public static void main(String[] args){
SubstractionableCalculator c1 = new SubstractionableCalculator();
c1.setOperands(10,20);
c1.sum();
c1.avg();
c1.substract();
}
}
부모와 자식 클래스에 avg()라는 메소드가 동일하게 있다.
부모 클래스에서는 반환값이 void이고, 자식 클래스에서는 반환값이 int이다.
그런데, 이 예제를 컴파일 시키면 에러가 난다.
자식 클래스에서 정의한 avg()메소드의 반환 타입이 부모 클래스의 avg()메소드의 반환타입과 호환되지 않아서 에러가 나게 된다.
즉, 부모 클래스의 메소드 형식과 자식 클래스의 메소드 형식이 일치하지 않는 경우, 오버라이딩을 할 수 없고 에러가 나게 된다. (오버라이딩을 위해서는 부모/자식 클래스에서의 반환타입이 일치해야 한다.)
2. 오버로딩(overloading)
: 오버로딩이란 클래스에 메소드를 정의할 때, 메소드의 이름은 같지만 매개변수의 자료형과 갯수를 다르게 해서 동일한 이름의 메소드를 정의할 수 있는 방법을 말한다.
public void setOperands(int left, int right){
System.out.println("setOperands 2");
this.left = left;
this.right = right;
}
public void setOperands(int left, int right, int third){
System.out.println("setOperands 3");
this.left = left;
this.right = right;
this.third = third;
}
setOperands()메소드 2개가 있다.
매개변수가 2개인 setOperands()메소드, 매개변수가 3개인 setOperands() 메소드가 있다.
오버로딩을 사용할때 주의할 점은,
void A();
int A();
이 두 메소드는 반환형만 다르고, 매개변수의 형식이 모두 동일하다.
이런 경우에는 오버로딩이 되지 않고 오류가 발생한다.
자바 입장에서는 사용자가 반환값이 있는 메소드를 호출한건지 반환값이 int인 메소드를 호출한건지 알 수 없기에
반환값만 다른 경우에는 오버로딩을 할 수 없다.