※ 본문은 혼자 공부한 내용을 기록한 글입니다. 오개념이 있다면 댓글로 알려주세요!
[ 1 ] Overriding
상속이란 자식 클래스에서 부모 클래스의 필드와 메소드를 물려받아 사용할 수 있는 것을 의미한다. 그렇다면 자식 클래스는 부모 클래스의 메소드를 무조건 그대로 사용해야 할까?
부모 클래스 메소드의 동작 방법을 변경하고 싶을 때 우리는 Java의 Overriding 기능을 활용할 수 있다.
class Parent {
int left;
int right;
public Parent(int left, int right)
{
this.left = left;
this.right = right;
}
public void sum()
{
System.out.println(this.left + this.right);
}
}
class Child extends Parent {
public Child(int left, int right)
{
super(left, right);
}
}
public class Main {
public static void main(String[] args) {
Child c1 = new Child(10, 20);
c1.sum(); // 30 출력
}
}
위 소스코드에서 Child 클래스는 Parent 클래스를 상속받아 Parent의 sum() 메소드를 사용할 수 있다.
큰 의미는 없지만, Child 클래스로 sum() 메소드를 사용할 때는 정답 정수 앞에 "두 수의 합은"이라는 문자열을 추가하고 싶다고 가정하자.
class Parent {
int left;
int right;
public Parent(int left, int right)
{
this.left = left;
this.right = right;
}
public void sum()
{
System.out.println(this.left + this.right);
}
}
class Child extends Parent {
public Child(int left, int right)
{
super(left, right);
}
@Override
public void sum()
{
System.out.println("두 수의 합은 " + (this.left + this.right));
}
}
public class Main {
public static void main(String[] args) {
Child c1 = new Child(10, 20);
c1.sum(); // "두 수의 합은 30" 출력
}
}
이때 우리는 Overriding을 활용하여 Child 클래스의 sum() 메소드 동작 방법을 변경할 수 있다.
@Override
public void sum()
{
System.out.println("두 수의 합은 " + (this.left + this.right));
}
가장 첫 줄의 @Override는 아래의 메소드가 부모 클래스의 메소드를 Overriding한 메소드임을 알려주는 annotation이다. annotation은 생략할 수 있지만 개발자의 실수를 방지하기 위해 작성하는 것을 권장한다.
그 다음은 Overriding할 메소드를 재정의한다. 이때 지켜야 할 원칙은 다음과 같다.
(1) 메소드의 이름이 같아야 한다. |
(2) 메소드 매개변수의 데이터 타입, 개수, 그리고 순서가 같아야 한다. |
(3) 메소드의 리턴 타입이 같아야 한다. |
위 원칙을 반드시 지켜야하며, 지키지 않는다면 error가 발생한다.
[ 2 ] Overloading
Overloading은 한 클래스에서 매개변수의 개수, 데이터 타입이 다르다면 같은 이름인 메소드를 여러 개 정의할 수 있는 기능이다.
public class Overloadpractice {
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)");}
public static void main(String[] args) {
Overloadpractice op = new Overloadpractice();
op.A();
op.A(1);
op.A("test");
}
}
위 소스코드에는 이름이 동일한 A()라는 메소드가 3개나 정의되어 있다. 하지만, 3개의 메소드가 서로 다른 매개변수를 가지고 있어 Overloading 된 상태이다.
실제로 위 소스코드를 실행하면 각기 다른 메소드가 실행되었음을 확인할 수 있다.
Overloading의 원칙은 다음과 같다.
(1) 메소드의 이름이 같아야 한다. |
(2) 메소드 매개변수의 개수, 데이터 타입, 순서가 달라야 한다. (매개변수의 이름은 달라도 상관없다) |
(3) 매개변수의 리턴 타입은 상관없다. 단, 매개변수의 개수, 데이터 타입, 순서가 완전히 동일할 때에는 리턴 타입만 다르다고 해서 Overloading되지 않는다. |
세 번째 원칙을 직접 확인해 보자.
public class Overloadpractice {
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)");}
int A(double arg1) {
System.out.println("int A(double arg1)");
return 1;
}
public static void main(String[] args) {
Overloadpractice op = new Overloadpractice();
op.A();
op.A(1);
op.A("test");
op.A(1.1);
}
}
마지막으로 정의된 int A(double arg1) 메소드는 나머지 메소드와 매개변수의 데이터 타입이 다르므로 문제 없이 Overloading된다.
하지만, 매개변수의 데이터 타입이 동일한 경우
중복된 메소드가 정의되었다는 에러를 확인할 수 있다.
[ 정리 ]
(1) Overriding: 자식 클래스에서 물려받은 부모 클래스 메소드를 재정의하여 동작 방법을 변경시키는 것
(2) Overloading: 한 클래스에서 매개변수의 개수, 데이터 타입이 다르다면 같은 이름을 가지는 메소드를 여러 개 정의할 수 있는 것
'Programming > Java' 카테고리의 다른 글
[Java] 추상 클래스(abstract class)와 인터페이스(interface) (1) | 2022.08.11 |
---|---|
[Java] 패키지(Package) (0) | 2022.08.05 |
[Java] 생성자 및 상속에서의 생성자 (0) | 2022.08.02 |
[Java] 클래스(class)의 구성과 클래스 멤버 및 인스턴스 멤버 (1) | 2022.08.01 |
[Java] 제네릭(Generic) (0) | 2022.07.31 |