코린이의 소소한 공부노트

메서드 오버라이딩 (+오버로딩과의 차이점) 본문

Java

메서드 오버라이딩 (+오버로딩과의 차이점)

무지맘 2022. 3. 22. 14:52

메서드 오버라이딩이란 상속받은 조상의 메서드를 자신에 맞게 변경하는 것을 말한다.

예시로, 2차원 좌표를 나타내는 Point 클래스를 상속받아 3차원 좌표를 나타내는 Point3D 클래스를 만들었다.

class Point{ // 2차원 좌표
	int x;
	int y;
	
	String getLocation() { // 객체의 x, y값 순서쌍으로 출력
		return "(x, y) = (" + x + ", " + y + ")";
	}
}

class Point3D extends Point{ // 3차원 좌표
	int z;
	
	String getLocation() { // 메서드 오버라이딩
		return "(x, y, z) = (" + x + ", " + y + ", " + z + ")";
	}
}

Point 클래스는 좌표가 2개지만, Point3D 클래스는 3개이기 때문에 getLocation 메서드를 그대로 상속받아 쓰면 3차원 좌표를 나타낼 수 없다. 그렇기 때문에 자신에게 맞게 변경하기 위해 메서드 내용을 덮어쓴 것이다. 여기서 구현부(내용)만 변경 가능하지, 메서드 선언부는 변경할 수 없다.

main 메서드에서 두 클래스를 이용해 객체를 생성해보고, 메서드를 사용해보자.

Point p1 = new Point();
p1.x=4;
p1.y=5;

Point3D p2 = new Point3D();
p2.x=6;
p2.y=2;
p2.z=9;

System.out.println(p1.getLocation()); // "(x, y) = (4, 5)"
System.out.println(p2.getLocation()); // "(x, y, z) = (6, 2, 9)"

출력 결과를 보면 알겠지만, 자기의 클래스에 있는 메서드가 호출이 된 것을 확인할 수 있다. Point3D 클래스는 Point 클래스의 멤버를 상속을 다 받긴 받지만, 메서드 호출 시 오버라이딩이 되어있다면 그것을 호출한다.

 

[오버라이딩의 조건]

1. 선언부가 조상 클래스의 메서드와 일치해야 한다.

  - 반환타입, 메서드 이름, 매개변수 목록 모두가 일치해야 한다.

2. 접근 제어자를 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없다.

  - 접근 허용 범위: public > protected > default(아무것도 붙이지 않은 것) > private

  - 조상이 default인데 자손이 public일 수 없다.

  - 2022.04.16 - [Java] - 제어자

3. 예외는 조상 클래스의 메서드보다 많이 선언할 수 없다.

class Parent{
    void method1() throws IOException {} // 예외 1개
}

class Child extends Parent{
    void method1() throws IOException, SQLException {} // 예외 2개 -> 에러
}

  - 예외에 관한 자세한 내용은 추후 게시 예정

 

[쿠키글 1] 오버로딩 vs 오버라이딩

오버로딩 비교 항목 오버라이딩
기존에 없는 새로운 메서드를 정의 상속받은 메서드 내용을 변경
관계 없음 상속과의 연관성 관계 있음
같음 메서드 이름 같음
같음 or 다름 메서드의 반환타입 같음
개수, 타입이 다름 메서드의 매개변수 같음

아래 코드를 보며 오버로딩과 오버라이딩을 확실히 구분할 수 있도록 해보자.

class Parent{
    void pmethod() {}
}

class Child extends Parent{
    void pmethod() {}      // 1번. 오버라이딩
    void pmethod(int x) {} // 2번. 1번의 오버로딩
    
    void cmethod() {}      // 3번. 새 메서드 정의
    void cmethod(int x) {} // 4번. 3번 오버로딩
    void cmethod() {}      // 5번. 3번 중복정의. 에러 발생
}

 

[쿠키글 2] 리팩터링

예시로 들었던 Point클래스는 생성자와 메서드 오버라이딩을 이용해 리팩터링이 가능하다.

명시하지 않았지만, 상속 관계는 Point -> Object이다.

class Point{
    int x;
    int y;

    Point(int x, int y){
        this.x = x;
        this.y = y;
    }

    // object클래스 오버라이딩
    // 선언부가 같아야하기때문에 public붙임
    public String toString() {
        return "(x, y) = (" + x + ", " + y + ")";
    }
}

// main 메서드 내부
Point p = new Point(7, 8);
System.out.println(p.toString()); // "(x, y) = (7, 8)"
// 위의 예시에서는 4줄이었던 것이 2줄로 줄어듦

System.out.println(p); // "(x, y) = (7, 8)"
// toString이 오버라이딩 되어있다면
// toString을 안 써도 같은 결과가 나옴

'Java' 카테고리의 다른 글

패키지와 클래스 경로  (0) 2022.04.13
생성자 super() vs 참조변수 super  (0) 2022.03.23
클래스 간의 관계 - 상속, 포함  (0) 2022.03.15
변수의 초기화  (0) 2022.03.12
생성자 this() vs 참조변수 this  (0) 2022.03.12