상속
- 기존 클래스의 속성과 기능을 그대로 물려받는다
- 기존 클래스의 필드와 메서드를 새로운 클래스에서 재사용하게 해준다
- extends 키워드를 사용한다(extends 대상은 하나만 선택 가능, 다중 상속 불가)
- 부모 클래스(슈퍼 클래스) : 상속을 통해 자신의 필드와 메서드를 다른 클래스에게 제공
- 자식 클래스(서브 클래스) : 부모 클래스로부터 필드와 메서드를 상속받는 클래스
상속 예제
- Car 클래스는 move() 라는 메소드를 가진다.
- ElectricCar 클래스는 move() 메소드를 사용할 수 있고, charge() 메소드를 가진다.
- GasCar 클래스는 move() 메소드를 사용할 수 있고, fillUp() 메소드를 가진다.
- Car 클래스를 부모 클래스로, ElectricCar, GasCar 클래스를 자식 클래스로 정의한다.
- 자식은 부모 클래스의 필드와 메소드를 사용할 수 있다.
Car 클래스
public class Car {
public void move() {
System.out.println("차를 이동합니다.");
}
public void openDoor() {
System.out.println("문을 엽니다.");
}
}
ElectricCar 클래스(Car 클래스 상속)
public class ElectricCar extends Car {
public void charge() {
System.out.println("차를 충전합니다.");
}
}
GasCar(Car 클래스 상속)
public class GasCar extends Car {
public void fillUp() {
System.out.println("기름을 주유합니다.");
}
}
상속 기능 확인 - Main
public class CarMain {
public static void main(String[] args) {
ElectricCar electricCar = new ElectricCar();
electricCar.openDoor();
electricCar.move();
electricCar.charge();
GasCar gasCar = new GasCar();
gasCar.move();
gasCar.fillUp();
}
}
ElectricCar 클래스가 Car 클래스의 move(), openDoor() 메소드를 활용할 수 있다
GasCar 클래스도 Car 클래스의 move() 메소드를 사용할 수 있다
물론, 자기가 가지고 있는 메소드들은 무조건 사용할 수 있다
상속은 특정 클래스의 기능은 그대로 활용할 수 있으면서, 자기 자신의 기능만을 추가하기에 좋은 옵션이다
또한, 부모 클래스에 기능을 추가하면 그 자식들은 모두 그 기능을 활용할 수도 있다
단일 상속
- 자바는 다중 상속을 지원하지 않는다(extends의 대상은 하나만 선택 가능)
- 다이아몬드 문제
- AriPlane 클래스에 move() 메소드가 있고, Car() 클래스에도 move() 메소드가 있다
- AirPlaneCar 라는 클래스를 정의하고 두 클래스를 모두 상속하려고 하면 move() 메소드는 어떤걸 써야하는지 모름
- 다이아몬드 문제
- 인터페이스의 다중 구현을 통해서 이런 문제를 피할 수 있다.
★ ★ 상속과 메모리 구조
- Car 클래스의 자식 클래스 ElectricCar 클래스를 인스턴스화하면 Car 클래스까지 포함해서 인스턴스를 생성한다.
- 참조값은 하나지만, 그 안에는 Car, ElectricCar 두가지 클래스 정보가 공존
- 상속 관계를 사용하면, 부모 클래스도 함께 생성
- 메소드 호출 시 변수의 타입(클래스)를 기준으로 선택
- new ElectricCar() - 자식 메소드 호출 시, ElectricCar의 메소드를 호출
- new ElectricCar() - 부모 메소드 호출 시, ElectricCar에 메소드 있는지 확인(없으면 부모 클래스 메소드 호출)
- 오버라이딩된 메소드가 우선 순위를 가진다
- 당연히 내 메소드가 있으면 그걸 쓰고, 없으면 부모의 메소드를 호출
- 부모에서도 못 찾으면, 상위 부모로 올라가서 찾는다(끝까지 못찾으면 컴파일 오류 발생)

상속과 메소드 오버라이딩
- 부모 타입의 기능을 자식이 재정의 하는 것을 오버라이딩
- 부모의 기능을 그대로 사용하고 싶지 않을때 활용
- 오버라이딩은 강제적인 조건은 아니기에, 자바는 다중상속이 안되는 부분(이 문제는 인터페이스로 해결)
- @Override 애노테이션 : 상위 클래스의 메소드를 오버라이딩 하는 것을 표현
- 오버라이딩 조건을 만족하지 않으면, 컴파일 에러 발생(실수 방지)
- 자식에 move() 메소드를 오버라이딩 하는데, 부모에 move()가 없으면 에러
오버라이딩 조건
- 같은 껍데기
- 메소드 이름이 같아야 한다
- 매개변수(파라미터) 타입, 순서, 갯수가 같아야 한다
- 반환 타입이 같아야 한다(하위 클래스 타입 가능)
- 예외 : 오버라이딩 메소드는 상위 클래스의 메소드보다 더 많은 체크 예외를 throws로 선언할 수 없다(더 적거나, 같은 수)
- static, final, private 키워드가 붙으면 오버라이딩 할 수 없다
- static: 오버라이딩은 인스턴스 단계에서 활용되는데, static은 클래스 단계에서 사용되어지므로 의미가 없다
- final: final은 재정의를 금지하고 있다
- private: 해당 클래스만 접근하므로, 하위 클래스가 접근할 수 없다
super - 부모 참조
- 부모와 자식이 필드명이 같거나, 메소드 오버라이딩이 되어 있으면 자식에서 부모의 필드나 메소드를 참조 할 수 없다
- 기본적으로 나의 필드명이나, 메소드를 호출하기 때문
- super 키워드 사용 시 부모 참조 가능
- 말 그대로 부모 클래스에 대한 참조
- super.부모필드명, super.부모메소드명
super - 생성자
- 상속 관계의 인스턴스 생성 시 메모리 내부에는 자식과 부모 클래스가 모두 생성되기에 각각의 생성자도 모두 호출되어야 한다
- 상속 관계 사용 시, 자식 클래스의 생성자에서 부모 클래스의 생성자를 반드시 호출
- super() 로 부모 클래스의 생성자 호출(부모 클래스가 기본 생성자인 경우 super() 생략 가능)
- 상속 관계에서 자식 클래스의 생성자 첫 줄에 super() 를 호출해야 한다(부모부터 초기화)
'Java > 김영한의 실전자바' 카테고리의 다른 글
| 스레드의 생성과 실행 (0) | 2024.08.15 |
|---|---|
| 프로세스와 스레드 (0) | 2024.08.13 |
| [김영한의 실전 자바 - 기본편] 자바 메모리 구조 (0) | 2024.01.21 |
| [김영한의 실전 자바 - 기본편] 기본형과 참조형 (0) | 2024.01.21 |
| [김영한의 실전 자바 - 기본편] 클래스 (0) | 2024.01.13 |