TIL(5) - 오버로딩에 이어서 오버라이딩에 대해 알아보자!
오버로딩(Overloading) - 서로 다른 매개변수/자료형을 갖는 여러 생성자/메서드를 같은 이름으로 선언하는 것
오버라이딩(Overriding) - 상속 관계에 있는 자식 클래스가 부모 클래스에서 정의된 메서드를 같은 자료형을 갖는 메서드로 재정의 하는 것
Java에서 자식 클래스는 private 멤버를 제외한 모든 메서드를 부모 클래스로부터 상속받는다. 상속받은 메서드들은 그대로 사용해도 되고, 자식 클래스가 재정의에서 사용 할 수도 있는데 후자의 방식을 메서드 오버라이딩이라고 말한다.
부모 클래스의 메서드 선언부(메서드명
, 리턴 타입
, 자료형의 순서
, 매개변수의 개수
)와 동일해야한다.
부모 클래스의 메서드보다 더 큰 범위의 예외를 선언할 수 없다.
부모 클래스의 메서드와 같거나 더 넒은 법위의 접근 제어자로만 변경할 수 있다.
→ 부모 : default
- 자식 : default
, protected
, public
→ 부모 : protected
- 자식 : protected
, public
→ 부모 : public
- 자식 : public
자동차는 기본적으로 색깔
은 White
에 운적석
은 Left
에 위치해 있다고 가정하면, 자동차의 한 종류인 Truck은 색깔
과 운전석
은 가지고 있지만 yellow
에 Right
에 위치해 있다고 가정할 수 있다.
여기서 자동차는 부모 클래스
, Truck은 자식 클래스
를 의미한다.
부모 클래스
public class Car {
public void color() {
System.out.println("부모: White");
}
public void driverSeat() {
System.cou.println("부모: Left");
}
}
자식 클래스
public class Truck extends Car {
public void color() {
System.out.println("자식: Blue");
}
public void driverSeat() {
System.out.println("자식: Right");
}
}
Main.java
public class Main {
public static void main(String[] args) {
// 오버라이드 된 메서드
Car car1 = new Truck();
car1.color();
car1.driverSeat();
Truck truck1 = new Truck();
truck1.color();
truck1.driverSeat();
}
}
출력
자식: Blue
자식: Right
자식: Blue
자식: Right
부모 클래스에서 2개의 메서드를 정의하였고 자식 클래스가 상속받아 2개의 메서드를 재정의하였다.
White
, Left
→ Blue
, Right
main
메서드에서 자식 클래스로 인스터스화 하고 메서드를 각각 호출한 결과 자식 클래스 메서드로 데이터가 출력되는 것을 확인할 수 있다.
자식 클래스에서 부모 클래스로부터 상속받은 메서드를 참조하기 위해 사용하는 참조 변수이다. 오버라이딩했을 때 부모의 메서드를 호출하려면 super.메서드명(매개변수)
를 사용하면 된다.
▶ 변수는 오버라이드 할 수 없으면 메서드만 오버라이드 가능하다.
*부모 클래스
public class Car {
public String horn = "부모: 빵빵!!";
public void color() {
System.out.println("부모: White " + color);
}
}
자식 클래스
public class Truck extends Car {
public String horn = "자식: 빠라빠라빠라람~";
public void color() {
System.out.println("자식: Blue");
}
// 부모 메서드 호출
public void parentColor() {
super.color();
}
public String getColor() {
return color;
}
// 부모 변수 접근
public String getParentColor() {
return super.color;
}
}
Main.java
public class Main {
public static void main(String[] args) {
Car car2 = new Truck();
// 오버라이드 된 메서드
car2.color();
// 변수는 오버라이드 불가 - 부모 클래스 호출
System.out.println(car2.horn);
Truck truck2 = new Truck();
// 오버라이드 된 메서드
truck2.color();
// super.color - 부모 메서드 호출하는 자식 메서드
truck2.parentColor();
// 변수는 오버라이드 불가 = 자식 클래스 호출
System.out.println(truck2.horn);
}
}
출력
자식: Blue
부모: 빵빵!!
자식: Blue
부모: White 부모: 빵빵!!
자식: 빠라빠라빠라람~
부모 클래스에서 1개의 변수와 1개의 메서드를 정의하였고 자식 클래스가 상속받아 각각을 재정의하였다.
빵빵!!
, White
→ 빠라빠라빠라람~
, Blue
main
메서드에서 부모 클래스를 자식 클래스로 인스터스화 하고 호출한 결과 메서드는 오버라이드 되어 자식 클래스 메서드로 데이터가 출력(Blue
)되었다. 반면에 변수는 부모 클래스 변수 데이터(빵빵!!
)가 출력되어 오버라이드 되지 않았다.
자식 클래스를 자식 클래스로 인스터스화 하고super
키워드로 호출한 메서드는 부모 클래스 메서드로 데이터가 출력(White
, 빵빵!!
)되었고, 변수는 자식 클래스 변수 데이터(빠라빠라빠라람~
) 그대로 출력되었다.