상속
상속은 부모가 자식에게 물려주는 행위를 말한다.
객체 지향 프로그램에서 부모 클래스의 필드와 메서드를 자식 클래스에게 물려줄 수 있다.
상속은 이미 잘 개발된 클래스를 재사용해서 새로운 클래스를 만들기 때문에 중복되는 코드를 줄여 개발 시간을 단축시킨다.
또한 클래스의 수정을 최소화할 수 있다. 부모 클래스를 수정하면 모든 자식 클래스에 수정 효과를 가져온다. 그렇기 때문에 유지보수도 편리해진다.

클래스 상속
현실에서는 부모가 자식을 선택해 상속하지만, 프로그램에서는 자식이 부모를 선택한다.
자식 클래스를 선언할 때 어떤 부모로부터 상속받을 것인지를 결정한다.
public class 자식클래스 extends 부모클래스 {
}
참고로 자바는 다른 언어와 달리 다중 상속을 허용하지 않는다.
부모 생성자 호출
자식 객체를 생성하면 부모 객체가 먼저 생성된 다음에 자식 객체가 생성된다.

모든 객체는 생성자를 호출해야 생성되는데, 부모 객체도 예외는 아니다.
부모 생성자는 자식 생성자의 맨 첫 줄에 숨겨져 있는 super()에 의해 호출된다.
super()는 컴파일 과정에서 자동으로 추가되며 부모의 기본 생성자를 호출한다.
//자식 생성자 선언
public 자식클래스(...) {
super(); //생략 가능 - 컴파일 시 자동 추가
...
}
부모 클래스에 기본 생성자가 없고 매개변수를 갖는 생성자만 있다면 코드를 직접 넣어줘야 한다.
이 코드는 매개값의 타입과 개수가 일치하는 부모 생성자를 호출한다.
//자식 생성자 선언
public 자식클래스(...) {
super(매개값, ...);
...
}
매서드 재정의
부모 클래스의 어떤 메서드는 자식 클래스가 사용하기에 적합하지 않을 수 있기 때문에 재정의해서 사용해야 한다.
메서드 오버라이딩(overriding)
상속된 메서드를 자식 클래스에서 재정의하는 것을 말한다.
메서드가 오버라이딩되었다면 해당 부모 메서드는 숨겨지고, 자식 메서드가 우선적으로 사용된다.
오버라이딩할 때 아래와 같은 규칙을 주의해야 한다.
- 부모 메서드의 선언부(리턴 타입, 메서드 이름, 매개변수)와 동일해야 한다.
- 접근 제한을 더 강하게 오버라이딩할 수 없다.(public -> private 변경 불가)
- 새로운 예외를 throws할 수 없다.
부모 메서드 호출
자식 메서드 내에서 부모 메서드를 호출하기 위해 super 키워드를 사용하면 숨겨진 부모 메서드를 호출할 수 있다.
이 방법은 부모 메서드를 재사용함으로써 자식 메서드의 중복 작업 내용을 없애는 효과를 가져온다.

final 클래스와 final 메서드
필드 선언 시 final을 붙이면 초기값 설정 후 값을 변경할 수 없다.
클래스 선언할 때 final 키워드를 class 앞에 붙이면 최종적인 클래스이므로 더 이상 상속할 수 없는 클래스가 된다.
즉, final 클래서는 부모 클래스가 될 수 없다.
메서드를 선언할 때도 마찬가지로 final 키워드를 붙이면 이 메서드는 최종적인 메서드이므로 오버라이딩할 수 없는 메서드가 된다.
접근 제한자 - protected
자바는 접근 제한자로 객체 외부에서 필드, 생성자, 메서드의 접근 여부를 결정한다.
접근 제한자는 public, protected, private의 세 가지 종류가 있다.

| 접근 제한자 | 제한 대상 | 제한 범위 |
| public | 클래스, 필드, 생성자, 메서드 | 없음 |
| protected | 필드, 생성자, 메서드 | 같은 패키지이거나, 자식 객체만 사용 가능 |
| (default) | 클래스, 필드, 생성자, 메서드 | 같은 패키지 |
| private | 필드, 생성자, 메서드 | 객체 내부 |
protected는 상속과 관련이 있다. 같은 패키지에서는 default처럼 접근이 가능하나, 다른 패키지에서는 자식 클래스만 접근을 허용한다.
타입 변환🌟
타입 변환은 타입을 다른 타입으로 변환하는 것을 말한다.
클래스의 타입 변환은 상속 관계에 있는 클래스 사이에서 발생한다.
자동 타입 변환

자식은 부모의 특징과 기능을 상속받기 때문에 부모와 동일하게 취급될 수 있다.
예를 들어 고양이가 동물의 특징과 기능을 상속받았다면 '고양이는 동물이다'가 성립한다.
그래서 Cat 객체를 생성하고 Animal 변수에 대입하면 자동 타입 변환이 일어난다.
Cat cat = new Cat();
Animal animal = cat;
// Animal animal = new Cat(); 도 가능하다

부모 타입으로 자동 타입 변환된 이후에는 부모 클래스에 선언된 필드와 메서드만 접근이 가능하다.
변수는 자식 객체를 참조하지만 변수로 접근 가능한 멤버는 부모 클래스 멤버로 한정된다.
그러나 자식클래스에서 오버라이딩된 메서드가 있다면 부모 메서드 대신 오버라이딩된 메서드가 호출된다. => 다형성

강제 타입 변환

자식 타입은 부모 타입으로 자동 변환되지만, 반대로 부모 타입은 자식 타입으로 자동 변환되지 않는다. 대신 캐스팅 연산자로 강제 타입 변환을 할 수 있다.
Parent parent = new Child(); //자동 타입 변환
Child child = (Child) parent; //강제 타입 변환
자식 객체가 부모 타입으로 자동 변환한 후에 자식 타입에 선언된 필드와 메서드를 꼭 사용해야 한다면 강제 타입 변환을 해서 다시 자식 타입으로 변환해야 한다.
다형성
사용 방법은 동일하지만 실행 결과가 다양하게 나오는 성질을 말한다.
객체 사용 방법이 동일하다는 것은 동일한 메서드를 가지고 있다는 뜻이다.
부모의 메서드를 오버라이딩하고 있다면, 오버라이딩된 내용이 다르기 때문에 실행 결과가 다르게 나오는 데 이것이 바로 다형성이다.

다형성을 구현하기 위해서는 자동 타입 변환과 메서드 재정의가 필요하다.
출처
'Study > Java' 카테고리의 다른 글
| [Java] 다중 인터페이스와 인터페이스의 상속 (0) | 2024.05.30 |
|---|---|
| [Java] 인터페이스 선언 및 구성 멤버 (0) | 2024.05.25 |
| [Java] 객체와 클래스 (0) | 2024.05.06 |
| [Java] 컴파일 과정 (0) | 2024.04.29 |
| [Java] 람다, 스트림, Optional (0) | 2024.04.22 |