춘식이왔엉 2022. 4. 12. 01:25

 

< 상속의 개념 >

✔상속(Inheritance)이란?

 

현실 세계

 •부모가 자식에게 물려주는 행위
 

 •부모가 자식을 선택해서 물려줌

 

객체 지향 프로그램
 
 •자식(하위, 파생) 클래스가 부모(상위) 클래스의 멤버를 물려받는 것
 
 •자식이 부모를 선택해 물려받음
 

 •상속 대상: 부모의 필드와 메소드

 

✔상속의 효과

- 부모 클래스 재사용해 자식 클래스 빨리 개발 가능

- 반복된 코드 중복 줄임

- 유지보수 편리성 제공

- 객체 다형성 구현 가능

✔상속 대상 제한

- 부모 클래스의 private 접근 갖는 필드와 메소드 제외

- 부모 클래스가 다른 패키지에 있을 경우, default 접근 갖는 필드와 메소드도 제외


< 클래스 상속 >

✔ extends 키워드

- 자식 클래스가 상속할 부모 클래스를 지정하는 키워드

 

< 부모 생성자 호출 ( super(...)) >

✔ 자식 객체 생성하면 부모 객체도 생성되는가?

--> YES

- 자식 객체 생성할 때는 부모 객체로부터 생성 후 자식 객체 생성

- 부모 생성자 호출 완료 후 자식 생성자 호출 완료

 

✔ 명시적인 부모 생성자 호출

- 부모 객체 생성할 때, 부모 생성자 선택해 호출

자식클래스(매개변수선언, ...) {
super(매개값, ...);
...
}

- super(매개값, ...) --> 매개값과 동일한 타입, 개수, 순서 맞는 부모 생성자 호출

- 부모 생성자 없다면 컴파일 오류 발생

- 반드시 자식 생성자의 첫 줄에 위치

- 부모 클래스에 기본(매개변수 없는) 생성자가 없다면 필수 작성

 

🧵예제

부모 - CellPhone / 자식 - DmbCellPhone

상속을 받아 실행시켜보자

1. 부모 클래스 CellPhone 생성

 

2. 자식 클래스 DmbCellPhone 생성 & 상속 받음

 

3. 자식클래스 DmbCellPhone의 실행 클래스 생성

-> 콘솔창을 보면, DmbCellPhone 객체를 생성할 때

부모 생성자 호출이 먼저 일어나고 자식 생성자 호출이 완료되는 것을 볼 수 있다.


< 메소드 재정의 Override >

부모 클래스의 상속 메소드를 수정해 자식 클래스에서 재정의하는 것

 

✔메소드 재정의 조건

- 부모 클래스의 메소드와 동일한 시그니처 가져야 함

- 접근 제한을 더 강하게 오버라이딩 불가능

- 새로운 예외(Exception) throws 불가

 

@Override 어노테이션

- 컴파일러에게 부모 클래스의 메소드 선언부와 동일한지 검사 지시
 
- 정확한 메소드 재정의 위해 붙여주면 OK

 

* 부모 메소드 사용(super)

- 메소드 재정의는 부모 메소드를 숨기는 효과를 가지므로,

  자식 클래스에서는 재정의된 메소드만 호출된다.

 

- 자식 클래스에서 수정되기 전 부모 메소드 호출 - super 사용

--> super는 부모 객체 참조 ( this는 자신 객체 참조 )

 

🧵예제1

메소드 재정의 시에 재정의된 메소드가 호출되는 것을 확인해보자.

1. 부모 클래스

 

2. 자식 클래스

- 메소드 areaCircle(double r) 재정의

 

3. 실행 클래스

 

🧵예제2

if문을 이용하여, 조건에 따라

재정의한 메소드를 사용하거나 또는 부모 클래스의 메소드를 호출

1. 부모 클래스

2. 자식 클래스 

3. 실행 클래스

4. 결과

-> 오버라이딩 되지 않은 부분에 대해서는 당연히 부모클래스의 메소드가 호출됨.

오버라이딩 된 fly() 메소드에서는,

if문에 따라 flymode=SUPERTSONIC인 경우에만 자식 클래스의 메소드가 호출되고,

나머지는 super.fly();를 통해 부모 클래스의 메소드가 호출 되었다.


< final 클래스와  final 메소드 >

✔final 키워드의 용도

- final 필드 : 수정 불가 필드

- final 클래스 : 부모로 사용 불가한 클래스  = 상속할 수 없다

- final 메소드 : 자식이 재정의할 수 없는 메소드 = 오버라이딩 불가

 

🧵예제

final 메소드를 만들어서 오버라이딩이 불가능한지 확인해보자.

1. 부모 클래스 Car

2. 자식클래스 SportsCar

- speedUp() 메소드는 오버라이딩이 가능하지만,

final 메소드인 stop()에서오버라이딩을 시도하자 오류가 발생하는 것을 볼 수 있다.


< protected 접근 제한자 > 

상속과 관련된 접근 제한자

- 같은 패키지 : default와 동일

- 다른 패키지 : 자식 클래스만 접근 허용

🧵예제

protected로 선언된 필드. 생성자. 메소드를 각각 

1. 같은 패키지의 클래스

2. 다른 패키지의 클래스

3. 다른 패키지의 자식 클래스

에서 접근할 때, 어떻게 되는지 확인 해보자.

 

* 패키지1 의 클래스 A 생성

 

* 패키지1의 클래스 B 생성 & 클래스 A에 접근

-> 전부 가능

 

* 패키지2의 클래스 C 생성 & 클래스 A에 접근

-> 전부 불가능

 

* 패키지2의 클래스 D 생성 -> A의 자식 클래스

-> 부모클래스의 생성자를 '호출'하는 것 가능 

     필드와 메소드 접근 가능.