객체 지향 에서는 부모 클래스를 자식 클래스에게 물려줄 수 있다.
이 때, 부모 클래스를 상위 클래스, 자식 클래스를 하위 클래스 또는 파생 클래스 라 한다.
상속을 이용하면 중복되는 코드도 줄지만, 부모 클래스의 수정으로 모든 자식 클래스도 수정되기 때문에 유지 보수 시간을 최소화도 가능하다.
자식 클래스를 선언할 때 어떤 부모 클래스를 상속받을 것인지를 결정한다. 부모 클래스는
extends
뒤에 기술한다.
class 자식클래스 extends 부모클래스 {
// 필드
// 생성자
// 메소드
}
예제)
class SprotsCar extends Car { ... }
SprotsCar
클래스는 Car
클래스를 상속받는다 는 의미이다.
위처럼 직접 입력하면서 확인해 보았는데, 상속관계에 있으면 메소드 호출에 더 용이하다.
자바에서 자식 객체를 생성하면, 부모 객체가 먼저 생성되고 그 다음에 자식 객체가 생성된다.
위의 실습에서 했던 코드를 기준으로 보면
public class CellPhone
public class DmbCellPhone extends CellPhone
이처럼 클래스가 DmbCellPhone
의 부모 클래스가 CellPhone
이라는 관계가 된다.
이는 생성과정에서도 나타나는데
DmbCellPhone dmbCellPhone = new DmbCellPhone();
위 처럼 객체를 생성하면 DmbCellPhone
만을 생성하는 듯 하지만, 사실은 부모격인 CellPhone
객체가 먼저 생성되고 자식 객체가 생성된다.
그래서 모든 객체는 클래스의 생성자를 호출해야만 생성된다.
이는 부모 객체도 에외가 아닌데 그렇다면 부모 객체를 생성하기 위한 부모 생성자는 어디서 오는걸까 하면...
사실 부모 생성자는 자식 생성자의 맨 첫 줄에서 호출된다.
그걸 예로 들어서, DmbCellPhone
의 생성자가 명시적으로 선언되지 않으면 컴파일러는 다음과 같은 기본 생성자를 생성한다.
public DmbCellPhone() {
super();
}
첫줄에 super();
가 생성된 것이 보인다. 역할은 '부모의 기본 생성자를 호출한다' 이다.
즉, CellPhone
클래스의 다음 생성자를 호출한다.
super(매개값);
는 매개값의 타입과 일치하는 부모 생성자를 호출한다.
super();
는 반드시 자식 생성자 첫 줄에 위치해야 한다.
자식 클래스에서 부모 클래스의 메소드를 다시 정의하는 행위
이같은 작업을 할 경우에는 주의해야 할 점이 있다.
- 부모의 메소드와 동일한 시그니처(리턴 타입, 메소드 이름, 매개 변수 목록)을 가져야 한다.
- 접근 제한을 더 강하게 재정의할 수 없다.
- 새로운 예외(Exception)를 throws 할 수 없다.
진짜 말이 너무 어려운것 같다...
접근 제한 재정의 관련
부모 메소드가public
접근 제한자일 경우 재정의 하는 자식 메소드는default
나private
접근 제한으로 수정이 불가능반대로는 가능하다. 부모 메소드가
default
접근 제한을 가지면 재정의하는 자식 메소드는default
또는public
접근 제한이 가능
진짜 말이 너무 어렵다 ㅋㅋㅋㅋㅋ
위의 이미지를 보면 꽤나 쉽게 이해가 가는데 말로 풀어놓으니까 너무 어렵다...
이처럼 재정의된 메소드 호출을 통한 값이 변경되는 것을 볼 수 있다.
자식 클래스에서 부모 클래스의 메소드를 재정의하면, 부모 클래스의된 자식 메소드만 사용된다.
단, 자식 클래스 내부에서super
키워드를 붙여서 부모 메소드를 호출할 수 있습니다.
이것도 실습을 통해서 좀 더 쉽게 이해가 가능하다.
가장 부모인 Airplane
클래스를 상속하는 SupersonicAirPlane
클래스가 존재한다.
이제 SupersonicAirPlane
에 상수를 선언해주고 그 값에 따라 출력을 다르게 해준다.
메서드 명이 같기 때문에 상황에 따라 상속받는 부모의 메서드를 호출 하거나 자식의 메서드를 호출한다.
이렇게 결과가 나오는 것을 알 수 있다.
final
키워드는 클래스, 필드, 메소드의 선언시에 사용이 가능하다.
해당 선언이 최종 상태이고 수정될 수 없음을 의미한다.
클래스 선언시
final
키워드를class
앞에 붙이면 이 클래스는 상속할 수 없는 클래스가 된다.
즉,final
클래스는 부모 클래스가 될 수 없어 자식 클래스를 만들 수 없다 는 의미이다.public final class 클래스 { ... }
메소드 선언시에 사용하면 이 또한 재정의가 불가능한 메소드가 된다.
즉, 부모 클래스를 상속해서 자식 클래스를 선언시 부모 클래스에 선언된final
메소드는 자식 클래스에서 재정의가 불가능하다.public final 리턴타입 메소드( [매개변수, ...] ) { ... }
상속 : 부모 클래스의 필드와 메소드를 자식 클래스에서 사용할 수 있도록 하는 것
메소드 재정의 : 부모 메소드를 자식 클래스에서 다시 정의하는 것
final 클래스 : final 키워드로 선언된 클래스는 부모 클래스로 사용할 수 없느 final 클래스이다.
final 메소드 : final 키워드로 선언된 메소드는 자식 클래스에서 재정의할 수 없는 final 메소드이다.