부모 클래스에 정의 된 것을 자식 클래스에서 재정의 하는 것을 말한다. (덮어 쓰는 것이다.)
오버라이딩 규칙
1. 리턴 타입, 메소드 이름, 매개변수가 동일해야 한다.
2. 접근 제한자를 더 강하게 할 수 없다. (public > private 안됨)
오버라이딩하면 해당 메소드(= 덮어쓴 메소드 = 자식 메소드)가 우선적으로 사용된다.
다음은 부모 클래스로부터 상속받은 method1()을 오버라이딩 한 코드다.
//부모 클래스
class Parents{
public void method1(){
System.out.println("부모의 메소드");
}
}
//자식 클래스
public class Child extends Parents{
@Override
public void method1() {
System.out.println("자식의 메소드");
}
public static void main(String[] args) {
Child ch = new Child();
ch.method1(); //자식의 메소드
}
}
오버라이딩 이전에는 자식타입객체.method1()을 하면 "부모 클래스"가 출력되었을 것이다.
자식 클래스에서 method1()을 오버라이딩 했기 때문에 이제는 "자식 클래스"가 출력된다.
@Override
컴파일 시 오버라이딩이 정확히 되었는지 체크해주는 역할, 생략해도 된다.
리턴 타입, 메소드 이름, 매개변수 중 하나라도 부모 클래스와 다르면 오버라이딩 한 것이 아니다. 완전히 다른 메소드이다.
다음은 부모 클래스와 매개변수만 다르고, 리턴 타입, 메소드 이름이 같은 코드다.
public class Child extends Parents{
public void method1(String name) {
System.out.println("자식의 메소드 " + name);
}
public static void main(String[] args) {
Child ch = new Child();
ch.method1();
ch.method1("민호");
}
}
결과
부모의 메소드
자식의 메소드 민호
메소드 이름만 같을 뿐, 상속받은 method1( )을 오버라이딩 한 것이 아니다.
ch.method1( )은 매개변수가 없는 부모의 method1을 호출한 것이고, ch.method1("민호")는 String 타입의 매개변수를 가지는 자식의 method1을 호출한 것이다. (자신과 같은 매개변수 타입을 가진 메소드를 찾아간다. )
상속 받은 것을 바꿀 수는 있지만 줄일 수는 없다.
자식 클래스가 오버라이딩해도 원본(부모의 메소드)을 사용할 수 있다.
바로 super( )를 통해 부모 메소드를 호출하는 것이다.
다음과 같이 super.method1( )을 작성하면, 오버라이딩 했어도 부모의 method1( )을 사용 할 수 있다.
//자식 클래스
public class Child extends Parents{
@Override
public void method1() {
super.method1();
System.out.println("자식의 메소드");
}
public static void main(String[] args) {
Child ch = new Child();
ch.method1();
}
}
결과는 다음과 같다.
부모의 메소드
자식의 메소드
상속에서 생성자를 만들때 super( )는 맨 처음에, 한 번만 호출 가능했다. 그러나 메소드에서는 위치와 횟수에 상관없이 호출 가능하다.
public class Child extends Parents{
@Override
public void method1() {
super.method1();
System.out.println("자식의 메소드");
super.method1();
}
public static void main(String[] args) {
Child ch = new Child();
ch.method1();
}
}
위와 같은 코드가 있다면 결과는 다음과 같다.
부모의 메소드
자식의 메소드
부모의 메소드