Language/JAVA

여덟째날 [상속 (1)]

구일일구 2022. 8. 1. 19:59
반응형

[목차]

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.

 

반응형