728x90
상속이 상위 클래스의 기능을 하위 클래스의 기능을 물려주는 행위라고 한다면
오버라이딩은 자식 클래스에서 상위 클래스의 기능에 새로운 기능을 추가하여 재정의하는 것을 말한다.
public class Calculator {
int left, right;
public Calculator(int left,int right) {
this.left = left;
this.right = right;
}
// Calculator의 메소드
void add() {
int result1 = left+right;
System.out.println("합은 "+result1);
}
}
public class SubstractionableCalculator extends Calculator {
public SubstractionableCalculator(int left,int right) {
super(left,right);
}
// SubstractionableCalculator의 메소드
public void add() {
// 만약 여기서 super.add();를 사용한다면 c1.add();에서 부모의 add 메소드도 같이 실행
System.out.println("재정의됨!! 결과는"+(this.left+this.right));
}
public void substract() {
int result3 = left-right;
System.out.println("차는 "+result3);
}
}
public class CalculatorDemo {
public static void main(String[] args) {
SubstractionableCalculator c1 = new SubstractionableCalculator(10,20);
c1.add(); // SubstractionableCalculator의 메소드가 호출된다.
}
}
오버라이딩을 하기 위해서는
- 부모의 메소드와 동일한 시그너처(리턴 타입, 메소드 이름, 매개 변수 리스트)를 가져야 한다.
- 접근 제한을 더 강하게 오버라이딩할 수 없다.
- 새로운 예외를 throws할 수 없다.
위 조건을 만족시켜야 한다.
오버로딩이란 클래스 내에 같은 이름의 메소드를 여러 개 선언하는 것을 말한다.
메소드의 이름이 같다고 하더라도 매개변수의 숫자, 데이터 타입이 다르다면 다른 메소드로 인식한다.
public class Calculator {
int left, right, third, arg;
public void setOprands(int left, int right) {
System.out.println("20과 40");
this.left = left;
this.right = right;
}
public void setOprands(int left, int right, int third) {
System.out.println("20과 40, 60");
this.left = left;
this.right = right;
this.third = third;
}
public void add() {
int result1 = left + right + third;
System.out.println("합은 "+result1);
}
public void avg() {
// this.left도 가능
// -> 지역변수가 없기 때문에 this.를 쓰지 않았다.
int result2 = (left+ right+ third)/3;
int result3 = (left+right)/2;
if (this.third != 0) {
System.out.println("평균은 "+result2);
} else {
System.out.println("평균은 "+result3);
}
}
}
public class CalculatorDemo {
public static void main(String[] args) {
Calculator c1 = new Calculator();
c1.setOprands(20, 40);
c1.avg();
c1.add();
System.out.println();
c1.setOprands(20, 40, 60);
c1.avg();
c1.add();
}
}
오버로딩 하기 위해서는
- 리턴 타입은 무관하다.
- 메소드 이름은 동일해야 한다.
- 매개변수의 타입, 매개변수의 개수, 매개변수의 순서 중 하나가 달라야 한다.
위 조건을 만족시켜야 한다.
public class OverloadingDemo {
void A (){System.out.println("void A()");}
void A (int arg1){System.out.println("void A (int arg1)");}
void A (String arg1){System.out.println("void A (String arg1)");}
// 1번째(void)를 호출할지 이 주석(int)을 처리할 지 모른다.
// int A (){System.out.println("void A()");} -> 오류
public static void main(String[] args) {
OverloadingDemo od = new OverloadingDemo();
od.A();
od.A(1);
od.A("코린이");
}
}
// 결과
// void A()
// void A (int arg1)
// void A (String arg1)
public class OverloadingDemo2 extends OverloadingDemo {
void A (String arg1, String arg2){System.out.println("sub class : void A (String arg1, String arg2)");}
void A (){System.out.println("sub class : void A ()");}
public static void main(String[] args) {
OverloadingDemo2 od = new OverloadingDemo2();
od.A();
od.A(1);
od.A("코린이");
od.A("코린이", "코린이");
}
}
// 결과
// sub class : void A ()
// void A (int arg1)
// void A (String arg1)
// sub class : void A (String arg1, String arg2)
OverloadingDemo2의 2행에서 정의된 메소드 A는 문자열을 데이터타입으로 하는 두개의 매개변수를 가지고 있다.
이러한 형태의 변수는 부모 클래스에서는 정의되어 있지 않기 때문에 메소드 오버로딩이 되는 것이다.
반면에 3행에서 정의된 메소드 A는 매개변수가 없다.
그리고 부모 클래스에는 이미 매개변수가 없는 메소드 A가 존재한다.
이 둘은 매개변수의 형태가 같기 때문에 오버로딩이 아니라 오버라이딩에 해당한다.
728x90