클래스 상속
자식 클래스를 선언할 때 어떤 부모 클래스를 상속받을 것인지 결정하고, 선택된 부모 클래스는 다음
과 같이 extends 뒤에 기술한다.
class 자식클래스 extends 부모클래스 {
// 필드
// 생성자
// 메소드
}
- 여러 개의 부모 클래스를 상속할 수 없다. 그러므로 extends 뒤에는 단 하나의 부모 클래스만 와야 한다.
- 부모 클래스에서 private 접근 제한을 갖는 필드와 메소드는 상속 대상에서 제외된다.
- 부모 클래스와 자식 클래스가 다른 패키지에 존재한다면 default 접근 제한을 갖는 필드와 메소드도 상속 대상에서 제외된다.
부모 생성자 호출
자식 객체를 생성하면, 부모 객체가 먼저 생성되고 그 다음에 자식 객체가 생성된다.
DmbCellPhone dmbCellPhone = new DmbCellPhone();
- DmbCellPhone 객체만 생성하는 것 처럼 보이지만, 사실은 내부적으로 부모인 CellPhone 객체가 먼저 생성되고 자식인 DmbCellPhone 객체가 생성된다.
이것을 메모리로 표현하면 다음과 같다.
부모 객체를 생성하기 위해 부모 생성자를 어디서 호출했을까?
-> 생성자가 명시적으로 선언되지 않았다면 다음과 같은 기본 생성자를 생성한다.
public DmbCellPhone() {
super(); // 부모의 기본 생성자를 호출
}
만약 직접 자식 생성자를 선언하고 명시적으로 부모 생성자를 호출하고 싶다면 다음과 같이 작성
자식클래스(매개변수선언, ...) {
super(매개값, ...);
...
}
- super(매개값, ...)는 매개값의 타입과 일치하는 부모 생성자를 호출한다.
- 매개값의 타입과 일치하는 부모 생성자가 없을 경우 컴파일 에러가 발생한다.
- super(매개값, ...)가 생략되면 컴파일러에 의해 super()가 자동적으로 추가되기 떄문에 부모의 기본 생성자가 존재해야한다.
- 부모 클래스에 기본 생성자가 없고 매개 변수가 있는 생성자만 있다면 자식 생성자에게 반드시 부모 생성자 호출을 위해 super(매개값, ...)를 명시적으로 호출해야 한다.
- super(매개값, ...)는 반드시 자식 생성자 첫 줄에 위치해야 하며, 그렇지 않으면 컴파일 에러가 발생한다.
메소드 재정의
- 부모 클래스의 메소드가 자식 클래스가 사용하기에 적합하지 않은 경우 상속된 일부 메소드는 자식 클래스에서 다시 수정해서 사용해야 한다.
- 메소드 재정의 방법
- 부모의 메소드와 동일한 시그니처(리턴 타입, 메소드 이름, 매개 변수 목록)을 가져야 한다.
- 접근 제한을 더 강하게 재정의할 수 없다.
- 새로운 예외(Exception)을 throws할 수 없다.
public class Calculator {
double areaCircle(double r) {
System.out.println("Calculator 객체의 arearCircle() 실행");
return 3.14159 * r * r;
}
}
<부모 클래스>
public class Computer extends Calculator {
@Override
double areaCircle(double r) {
System.out.println("Computer 객체의 areaCircle() 실행");
return Math.PI * r * r;
}
}
<자식 클래스>
- 부모 메소드 호출
- 자식 클래스 내부에서 재정의된 부모 클래스의 메소드를 호출해야 하는 상황이 발생한다면 명시적으로 super 키워드를 붙여서 부모 메소드를 호출할 수 있다.
- super.부모메소드();
- 자식 클래스 내부에서 재정의된 부모 클래스의 메소드를 호출해야 하는 상황이 발생한다면 명시적으로 super 키워드를 붙여서 부모 메소드를 호출할 수 있다.
final 클래스와 final 메소드
- final 키워드는 클래스, 필드, 메소드를 선언할 때 사용할 수 있는데 해당 선언이 최종 상태이고 결코 수정될 수 없음을 뜻한다.
- 필드를 선언할 때 final이 지정되면 초기값 설정 후 더 이상 값을 변경할 수 없다.
- 클래스와 메소드를 선언할 때 final 키워드가 지정되면 상속과 관련이 있다는 의미이다.
- 상속할 수 없는 final 클래스
- 클래스를 선언할 때 final 키워드를 class 앞에 붙이면 이 클래스는 최종적인 클래스이므로 상속할 수 없는 클래스가 된다.
public classs NewString extends String {...} // 이런 형태가 불가능
- 재정의할 수 없는 final 메소드
- 메소드를 선언할 때 final 키워드를 붙이면 이 메소드는 최종적인 메소드이므로 재정의할 수 없는 메소드가 된다.
- 아래와 같이 재정의 불가능
©Override
public void stop() {
System.out.printin("스포츠카를 멈춤,,);
speed = 0;
}
protected 접근 제한자
- public, protected, default, private와 같이 네 가지 종류가 있다.
- protected는 public과 default 접근 제한의 중간쯤에 해당한다.
- 같은 패키지에서는 default와 같이 접근 제한이 없지만 다른 패키지에서는 자식 클래스만 접근을 허용
확인 문제
1. 자바의 상속에 대한 설명입니다. 맞는 것에 O표, 틀린 것에 X표 하세요.
① 자바는 다중 상속을 허용한다. ( X )
② 부모의 메소드를 자식 클래스에서 재정의(오버라이딩)할 수 있다. ( O )
③ 부모의 private 접근 제한을 갖는 필드와 메소드는 상속의 대상이 아니다. ( O )
④protected 멤버는 같은 패키지의 모든 클래스와 다른 패키지의 자식 클래스만 접근할수 있다. ( O )
2. 메소드 재정의(오버라이딩)에 대한 설명입니다. 맞는 것에 o표, 틀린 것에 x표 하세요.
① 부모의 메소드는 숨김 효과가 나타난다. ( O )
② 재정의 시 접근 제한을 더 강하게 할수 있다. ( X )
③ @Override를 붙이면 컴파일러가 재정의를 확인한다. ( O )
④ 부모 메소드를 호출하고 싶다면 super 키워드를 사용할 수 있다. ( O )
3. final 클래스, final 필드, final 메소드에 대한 설명입니다. 맞는 것에 O표, 틀린 것에 X표 하세요.
① 모두상속과관련이 있다. ( X )
② final 메소드를 가진 클래스는 부모 클래스가 될 수 없다. ( X )
③ final 메소드는 재정의를 할수 없다. ( O )
④ final 클래스는 final 필드가 반드시 있어야 한다. ( X )
4. Parent 클래스를 상속해서 Child 클래스를 다음과 같이 작성했는데, Child 클래스의 생성 자에서 컴파일 에러가 발생했습니다. 그 이유를 설명해보세요.
- 부모 생성자를 호출하지 않았다. 6줄 7줄 사이에 super(name);을 추가해야한다.
5. Parent 클래스를 상속받아 Child 클래스를 다음과 같이 작성했습니다. ChildExample 클 래스를 실행했을 때 호출되는 각 클래스의 생성자의 순서를 생각하면서 출력 결과를 작성해보세요.
Parent(String nation) call
Parent() call
Child(String name) call
Child() call
'JAVA' 카테고리의 다른 글
추상 클래스 (0) | 2022.10.31 |
---|---|
타입 변환과 다형성 (0) | 2022.10.31 |
패키지와 접근 제한자 (0) | 2022.10.13 |
인스턴스 멤버와 정적 멤버 (0) | 2022.10.13 |
메소드 (0) | 2022.10.13 |