일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- database
- 코딩테스트
- java
- array
- Binary Search
- Method
- two pointers
- simulation
- Tree
- dynamic programming
- 파이썬
- hash table
- string
- 구현
- Matrix
- geometry
- Math
- Data Structure
- bit manipulation
- 자바
- Binary Tree
- SQL
- implement
- Counting
- 코테
- Class
- Number Theory
- greedy
- sorting
- Stack
- Today
- Total
코린이의 소소한 공부노트
메서드 오버라이딩 (+오버로딩과의 차이점) 본문
메서드 오버라이딩이란 상속받은 조상의 메서드를 자신에 맞게 변경하는 것을 말한다.
예시로, 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일 수 없다.
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 |