안녕하세요, 코린이의 코딩 학습기 채니 입니다.
개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.
메소드 오버라이딩(Overriding, Override)이란?
- 부모 클래스에게 상속받은 메소드와 동일한 이름의 메소드를 재정의하는 것
- 부모의 메소드를 자신이 만든 메소드로 덮어쓰는 개념
- 부모 메소드가 던지는 예외를 제거하거나 개수를 줄일 수 있음
- 부모 메소드를 오버라이드한 경우에도, 해당 메소드 안에서 super 키워드로 호출 가능
메소드 오버라이딩 조건
① 부모 클래스의 메소드와 시그니처 및 리턴 타입 동일
② 부모 클래스의 메소드보다 접근 지정자의 범위가 같거나 넓어야함 (private → default → protected → public)
단, private은 직접 접근이 불가하므로 오버라이딩 불가
final 메소드 또한 오버라이딩 불가
class Parent {
public void say() {
System.out.println("부모클래스");
}
}
class Child extends Parent {
@Override
public void say() {
System.out.println("자식클래스");
}
}
@Override 어노테이션
- 오버라이딩 유효성 확인
public class InheritanceBasicMain {
public static void main(String[] args) {
Parent parent = new Parent();
parent.say();
Child child = new Child();
child.say();
}
}
@콘솔출력값
부모클래스
자식클래스
상속 받은 say()메소드를 오버라이딩하여 사용하였습니다.
만일 오버라이딩을 하지 않은 채 say()메소드를 호출하면 부모 클래스로부터 물려받은 그대로 say()메소드를 출력하게될 것입니다.
따라서 "부모클래스"가 리턴 되겠죠.
메모리 구조는 아래와 같습니다.
Parent 클래스의 객체를 생성하였을 때의 메모리 구조입니다.
객체 내부에 say()메소드의 위치값을 갖고 있고 실제 say()는 메소드 영역에 정의가 되어있습니다.
Child 클래스의 객체를 생성하였을 때의 메모리 구조입니다.
상속 시 객체 생성 순서는 부모 클래스의 객체가 먼저 생성된 후 자식 클래스 객체가 생성됩니다.
따라서 부모 클래스가 먼저 생성되었으므로 부모 클래스의 say()메소드가 메소드 영역에 생성될 것입니다.
그 후 자식 클래스 객체가 생성되었는데, 자식 클래스의 say()메소드 역시 메소드 영역에 저장되지만, 이미 Parent 객체의 say()메소드가 존재하고 있는 상황입니다.
이때, Child 객체의 say()메소드가 이미 생성되어있는 Parent 객체의 say()메소드를 덮어쓰기, 오버라이딩 하게 되는 것입니다.
그러니 child.say() 메소드를 호출하면 "자식클래스"가 리턴 되는 것이죠.
오버라이딩이 되었다고 하여 기존 Parent 클래스의 say()가 없어진 것일까요?
아닙니다. 오버라이딩은 이전 메소드 위에 새로운 메소드가 올라 타고 있는 것이므로 언제든 밑에 깔려있는 메소드를 가져와서 사용할 수 있습니다.
super키워드를 사용하여 호출해주면 됩니다.
class Parent {
public void say() {
System.out.println("부모클래스");
}
}
class Child extends Parent {
@Override
public void say() {
super.say();
System.out.println("자식클래스");
}
}
@콘솔출력값
부모클래스
자식클래스
만일 Parent parent = new Child(); 일 때는 어떻게 작동할까요?
class Parent {
public void say() {
System.out.println("부모클래스");
}
}
class Child extends Parent {
@Override
public void say() {
super.say();
System.out.println("자식클래스");
}
}
public class InheritanceBasicMain {
public static void main(String[] args) {
Parent parent = new Child();
parent.say();
}
}
@콘솔출력값
자식클래스
오버라이딩이 적용된 "자식클래스"가 출력됩니다.
그 이유는 Child() 생성자로 객체가 생성되기 때문에 부모 클래스인 Parent 객체가 먼저 만들어진 후 Child 객체가 생성됩니다.
이 과정에서 메소드 영역에서는 say() 메소드의 오버라이딩이 발생합니다.
Parent 타입의 참조변수를 사용하고 있으므로 parent 참조변수는 Parent객체를 가리키고 있을 겁니다.
따라서 parent.say()는 Parent 객체 내에 있는 say()메소드를 호출하라!는 것인데 이미 오버라이딩이 진행된 후이기 때문에 오버라이딩이 적용된 "자식클래스"가 출력되는 것이죠.
'Java > Java' 카테고리의 다른 글
상속) is-a-상속관계, has-a-포함관계, 강집합, 약집합 (0) | 2022.03.22 |
---|---|
상속) super 키워드, super() 메소드, protected 접근 제한자 (0) | 2022.03.22 |
상속) 최상위 클래스 Object, toString(), equals(Object obj), hashCode(), clone() (0) | 2022.03.21 |
상속) 상속의 특징, 생성자 상속 여부 (0) | 2022.03.21 |
객체 지향 3대 원칙) 상속에 대해서, 상속 시 메모리 구조 (0) | 2022.03.21 |