여덟째날 [상속 (1)]
[목차]
1. 상속 개념
2. 클래스 상속(extends)
3. 부모 생성자 호출(super(...))
4. 메소드 재정의(Override)
5. final 클래스와 final 메소드
6. protected 접근 제한자
7. 타입 변환과 다형성(polymorphism)
[1] 상속 개념
* 상속이란?
- 현실세계 : 부모가 자식에게 물려주는 행위, 부모가 자식을 선택해서 물려줌
- 객체지향프로그램 : 자식 클래스가 부모 클래스의 멤버(필드, 메소드, 생성자)를 물려받는 것, 자식이 부모를 선택해 물려받음, 부모 + 추가 가능
* 상속의 효과
- 부모 클래스를 재사용해 자식 클래스를 빨리 개발 가능
- 반복된 코드의 중복을 줄임
- 유지 보수가 편리함
- 객체 다형성 구현 가능
* 상속 대상 제한
-부모 클래스의 private 필드와 메소드 X
- 다른 패키지에 있을 경우, default 필드와 메소드X
[2] 클래스 상속
* extends 키워드
- 자식 클래스가 상속할 부모 클래스를 지정하는 키워드
//부모 클래스
public class A{
int field1;
void method1(){...}
}
//자식 클래스
public class B extends A{
String field2;
void metho2(){...}
}
- 자바는 단일 상속 : 부모 클래스 나열 불가
class 자식클래스 extends 부모클래스1, X부모클래스2X{
}
[3] 부모 생성자 호출(super(...))
* 부모가 없는 자식이 없음
- 자식 객체를 생성할 때는 부모 객체로부터 생성 후, 자식 객체 생성
- 부모 생성자 호출 완료 ➡️ 자식 생성자 호출 완료
- 상속을 받으면, 부모 객체가 먼저 올라가고 그 후에 자식 객체가 올라감
* super(매개값) : 명시적인 부모 생성자 호출
자식클래스 (매개변수선언,...){
super(매개값);
...
}
- 부모 객체를 생성할 때, 부모 생성자를 선택해서 호출 : 오버라이딩 되어 있을 경우 ➡️ super 사용
- super(매개값...) : 매개값과 동일한 타입, 개수, 순서 맞는 부모 생성자 호출
- 부모 생성자가 없다면 오류
- super 키워드는 반드시 자식 생성자의 첫 줄에 위치
-부모가 기본 생성자만 사용했다면, super가 필요 없음 / 그러나 기본 생성자가 아니라면 super가 필요
- 부모 클래스에 기본(매개변수 없는) 생성자가 있다면 안해도 됨 / 기본 생성자가 없다면 해야 함
[4] 메소드 재정의(Override)
* 메소드 재정의(@Override)
- 부모 클래스의 상속 메소드 수정해 자식 클래스에서 재정의하는 것
* 메소드 재정의 조건
- 부모 클래스의 메소드와 동일한 시그니처를 가져야 함
- 자식 클래스에서 접근 제한을 더 강하게 오버라이딩 불가 (public을 default, private로 수정 불가) (default는 public으로 수정 가능)
- 새로운 예외(Exception) throws 불가
* Override 어노테이션
- 컴파일러에게 부모 클래스의 메소드 선언부와 동일한지 검사 지시
- 정확한 메소드 재정의를 위해 붙여주면 ok
*메소드 재정의 효과
- 부모 메소드가 숨겨지는 효과 발생 : 재정의된 자식 메소드 실행
* 부모 메소드 사용(super)
- 메소드 재정의는 부모 메소드를 숨기는 효과 : 자식 클래스에서는 재정의된 메소드만 호출됨
- 자식 클래스에서 수정되기 전 부모 메소드 호출 : super 사용
- super는 부모 객체 참조 (참고: this는 자신 객체 참조)
[5] final 클래스와 final 메소드
* final 키워드의 용도 - 체크만 하면 됨
- final 필드 : 수정 불가 필드
- final 클래스 : 부모로 사용 불가한 클래스 (System, String은 final이 붙어서 상속X)
- final 메소드 : 자식이 재정의할 수 없는 메소드
* 상속할 수 없는 final 클래스 : 자식 클래스 만들지 못하도록 final 클래스로 생성
* 오버라이딩(재정의) 불가한 final 메소드 : 자식 클래스가 재정의 못하도록 final 메소드로 생성
[6] protected 접근 제한자
* protected 접근 제한자 : 상속과 관련된 접근 제한자
- 같은 패키지 : default와 동일 : 모두 쓸 수 있음
- 다른 패키지 : 자식 클래스만 접근 허용
[7] 타입변환과 다형성
* 다형성
- 같은 타입이지만 실행 결과가 다양한 객체 대입(이용) 가능한 성질
- 부모 타입에는 모든 자식 객체가 대입 가능
- 자식 타입은 부모 타입으로 자동 타입 변환됨
- 효과 : 객체 부품화 가능
* 상속 관계에서 자동 타입 변환
- 프로그램 실행 도중에 자동 타입 변환이 일어나는 것
- 바로 위의 부모가 아니더라도 상속 계층의 상위면 자동 타입 변환 가능 : 변환 후에는 부모 클래스 멤버만 접근 가능
* 필드의 다형성
- 부모 타입으로 자동 변환
- 재정의된 메소드 (오버라이딩)
* 매개변수의 다형성 (클래스 타입일 경우)
- 해당 클래스의 객체 대입이 원칙이지만, 자식 객체를 대입하는 것도 허용한다
- 자동 타입 변환
- 매개변수의 다형성
* 강제 타입 변환(Casting)
- 부모 타입을 자식 타입으로 변환하는 것
- 조건 : 자식 타입을 부모 타입으로 자동 변환 후, 다시 자식 타입으로 변환할 때 (부모 객체를 생성할때, 자식 객체를 활용한 경우)
- 필요한 경우1 : 자식 타입이 부모 타입으로 자동 변환(부모 타입에 선언된 필드와 메소드만 사용 가능)
- 필요한 경우2 : 자식 타입에 선언된 필드와 메소드를 다시 사용해야 할 경우
자식클래스 변수 = (자식클래스) 부모클래스타입;
* 객체 타입 확인(instanceof)
- 부모 타입이면 모두 자식 타입으로 강제 타입 변환할 수 잇는 것은 아님 : ClassCastException예외 발생 가능
- 먼저 자식 타입인지 확인 후 강제 타입 실행해야 함
- 좌항의 객체가 우항의 타입으로 객체가 생성되었다면 true 산출, 아니면 false 산출
- 좌항에 보통 부모 타입 / 우항에 자식 타입 으로 놓고 사용
boolean result = 좌항 (객체) instanceof 우항 (타입)
✅ 코드 분석 시, 변수가 무엇을 뜻하는지 알것
[정리]
* 모든 것을 외워야하는 것은 아니다 : 툴을 사용하니까 알아서 고쳐줄거야
* 프로그램의 기본은 틀 - 틀부터잡고, 메인은 나중에
* 메소드만드는 이유 - 만들고 나서 재활용하기 위해
* 상속 개념 배웠고
* 클래스 상속 받을 땐 : extends 사용
* 부모 생성자 호출 : super
* 메소드 재정의 : @Override
* 상속과 연관
- final 클래스, final 메소드 : 상속받을 수 없고, 오버라이딩할 수 없다
- protected 접근 제한자 : 다른 패키지의 상속받은 녀석, 내 패키지만 사용가능
- 타입변환과 다형성
- 다형성 : 같은 타입이지만 실행 결과가 다양한 객체 대입(이용) 가능한 성질 : 타이어 - 한국타이어 - 금호타이어
- 자동 타입 변환
Cat meow = new Cat()
Animal Ani = meow; //(o)
Animal Ani = new Cat(); //(o)
- 하나의 배열로 객체 관리 : 객체 명을 정하지 않고 만듦 : 코드를 줄이고 한번에 편하게 관리하자는 의미에서 객체 명을 정하지 않기 때문에, 굳이 객체 명을 정하지 않는다.
Tire t = new Tire(); //객체 명을 정해서 작업하면, t를 통해서 메모리에 접근해 여러 작업 가능
t.roll();
.....
new Tire().roll(); //한번만 접근을 하고, 그 다음 번엔 접근할 수 없음
-매개변수의 다형성
클래스 타입일 경우 : 해당 클래스의 객체 대입이 원칙이나 자식 객체 대입도 허용
//Vehicle을 상속받은 Bus를 이용해서 사용할 수 있다.
Vehicle vv = new Bus();
//그치만 다형성을 만들어서, 한 번에 모든 걸 작업할 수 있게 만든다.
부모 클래스를 잘 만들어야함. 자식을 쉽게 확장시킬 수 있기 때문.
public class TestEx1 {
public static void main(String[] args) {
System.out.println("Hello Java1");
TestEx1 tt = new TestEx1();
System.out.println(tt);
System.out.println(tt.toString());
- 강제 타입 변환 : 자식 타입을 부모 타입으로 자동 변환 후(부모 메소드엔 접근이 되지만, 자식 메소드에 접근불가하기 때문), 다시 자식 타입으로 변환할 때
-instanceof : 왼쪽의 객체가 오른쪽 껄로부터 만들어질 수 있는지 확인하는것. 만들어진게 맞다면 true. 아니라면 false.