📝 오버라이드 ( Override )
- 부모 클래스로부터 상속받은 메서드의 기능을 재정의 하는 것을 말한다.
// 부모 클래스
class Hello {
public void say() {
System.out.println("Hello!!!!!");
}
}
// 자식 클래스
class Korean extends Hello {
public void say() { // 부모 클래스의 say() 메서드를 재정의(오버라이드)
System.out.println("안녕하세요.");
}
}
// Main 클래스
public class Main {
public static void main(String[] args) {
Korean k = new Korean();
k.say();
}
}
👉 실행 결과
안녕하세요.
❗ 자식 클래스인 Korean에서 부모 클래스의 메서드인 say()를 재정의 하였기 때문에,
Korean 클래스의 객체는 부모 클래스의 메서드 기능에 접근하지 못한다.
// 부모 클래스
class Hello {
public void say() {
System.out.println("Hello!!!!!");
}
}
// 자식 클래스
class Korean extends Hello {
public void say() { // 부모 클래스의 say() 메서드를 재정의(오버라이드)
super.say(); // super 키워드 사용
System.out.println("안녕하세요.");
}
}
// Main 클래스
public class Main {
public static void main(String[] args) {
Korean k = new Korean();
k.say();
}
}
👉 실행 결과
Hello!!!!!
안녕하세요.
❗ super 키워드는 부모 클래스의 메서드를 호출하는 기능을 가지고 있기 때문에
Override 된 자식 클래스의 메서드에서 super 키워드를 사용하면,
재정의 되기 이전의 부모 클래스에 대한 메서드를 호출할 수 있다.
❗ 즉 부모의 메서드를 호출한 뒤에 추가적인 기능을 정의하고 있으므로,
부모의 원본 메서드에 대한 기능 확장 효과가 있다.
부모 클래스의 say() 메서드를 재정의 하는 과정에서 개발자의 실수로 인해
"sai()"라고 메서드가 추가되었다면, Java는 새로운 메서드를 추가한 것으로 인식하고,
특별한 에러를 표시하지 않는다.
이 때 부모의 메서드를 오버라이드하는 것이라는 걸 컴파일러에게 알려주는
역할을 하는 것이 @Override 이다.
"@Override"은 이 키워드가 명시된 위치 아래에 정의되는 메서드가 부모 클래스에
존재하지 않을 경우 구문 에러로 처리한다.
즉 부모 클래스의 메서드를 재정의 하고자 할 경우 의도치 않은 실수를 예방하기 위한
'오타 방지 옵션'이다.
여러 개의 메서드를 재정의 한다면 재정의 되는 모든 메서드를 위에 각기 명시해야 한다.
// 부모 클래스
class Hello {
public void say() {
System.out.println("Hello!!!!!");
}
}
// 자식 클래스
class Korean extends Hello {
@Override
public void sai() { // 🔥 ERROR - say()메서드 이름이 틀렸기 때문에 구문 에러가 난다.
System.out.println("안녕하세요.");
}
}
📝 오버로드 ( Overload )
- 한 클래스 내에 같은 이름의 메서드를 여러 개 정의하는 것을 말한다.
public class Calc {
int add (int a, int b) {
return a + b;
}
int add (int a, int b, int c) { // 파라미터 개수가 다른 경우
return a + b + c;
}
double add (double a, double b) { // 파라미터 타입이 다른 경우
return a + b;
}
}
public class Main {
public static void main(String[] args) {
Calc c = new Calc();
System.out.println(c.add(2, 4));
System.out.println(c.add(2, 4, 6));
System.out.println(c.add(1.2, 1.3));
}
}
👉 실행 결과
6
12
2.5
public class Article {
private int seq; // 글 번호
private String subject; // 글 제목
private String writer; // 글 작성자
//파라미터가 있는 생성자
public Article(int seq, String subject, String writer) {
this.seq = seq;
this.subject = subject;
this.writer = writer;
}
public Article(int seq, String writer) { // this 키워드를 사용한 생성자 Overload
this(seq, "제목없음", writer);
}
public Article(int seq) { // this 키워드를 사용한 생성자 Overload
this(seq, "제목없음", "익명");
}
// toString()
public String toString() {
return "Article [seq = " + seq + ", subject = " + subject + ", writer = " + writer + "]";
}
}
public class Main {
public static void main(String[] args) {
Article a1 = new Article(1, "첫 번째 게시물", "자바학생");
System.out.println(a1.toString());
Article a2 = new Article(2, "자바학생2");
System.out.println(a2); // 이렇게 객체만 출력해도 toString을 우선적으로 찾아서 실행시켜준다.
// 단, toString이 정의되지 않으면 주소값이 나온다.
Article a3 = new Article(3);
System.out.println(a3);
}
}
👉 실행 결과
Article [seq = 1, subject = 첫 번째 게시물, writer = 자바학생]
Article [seq = 2, subject = 제목없음, writer = 자바학생2]
Article [seq = 3, subject = 제목없음, writer = 익명]
오버라이드(Override) | 오버로드(Overload) | |
---|---|---|
정의 | 상속받은 메서드의 내용을 변경하는 것 | 기존에 없는 새로운 메서드를 정의하는 것 |
조건 | 메서드 이름, 파라미터 개수와 타입, 리턴타입이 모두 동일해야 한다. | 메서드 이름은 동일하지만 파라미터 개수와 타입이 달라야 한다. |
관계 | 상속 관계 | 동일한 클래스 내 or 상속 관계 |