PengTory

[Java] 상속 (Inheritance) 본문

Java

[Java] 상속 (Inheritance)

펭토리 2023. 3. 10. 12:24

1. 상속의 특징

상속은 부모가 자식에게 물려주는 행위를 말한다.

우리가 흔히 생각하는 부모가 자식에게 주는 상속과 달리 프로그램에서는 자식이 부모를 선택한다.

또한 다른 언어와 달리 자바는 다중 상속을 허용하지 않는다.

 

아래 코드를 보면 자식 객체만 생성하고 있고 부모 객체를 따로 생성하고 있지 않다. 그러나 자식 객체에 "자식 객체 생성" 그리고 부모 객체에 "부모 객체 생성"이라는 코드를 넣고 실행해보면 다음 사진과 같은 실행 결과가 나온다.

자바에서 자식 객체를 생성하면 부모 객체가 먼저 생성된 다음에 자식 객체가 생성된다는 것을 알 수 있다. 

또한 부모 객체의 실행이 먼저인 것도 확인 가능하다.

public class SmartPhoneExample extends Object {

	public static void main(String[] args) {
		SmartPhone myPhone = new SmartPhone("갤럭시", "은색");
		
		// java.lang 패키지에 있는 것들은 import하지 않아도 됨 -> ex) System, Object...
		System.out.println("모델: " + myPhone.model);
		System.out.println("색상: " + myPhone.color);
		
		System.out.println("와이파이 상태: " + myPhone.wifi);
		
		myPhone.bell();
		myPhone.sendVoice("여보세요.");
		myPhone.receiveVoice("안녕하세요! 저는 홍길동인데요.");
		myPhone.sendVoice("아~ 네, 반갑습니다.");
		
		myPhone.hangUp();
		
		myPhone.setWifi(true);
		myPhone.internet();

	}

}

실행결과

2. 메소드 재정의

어떤 메소드는 자식 클래스가 사용하기에 적합하지 않을 수 있다. 이러한 메소드는 자식 클래스에서 재정의해서 사용해야 하며 이것을 메소드 오버라이딩 이라고 한다.

 

->  메소드 오버라이딩 (Overriding) (:= ovverwrite)

메소드 오버라이딩은 상속된 메소드를 자식 클래스에서 재정의하는 것을 말한다. 메로스다 오버라이딩 된다면 해당 부모 메소드는 숨겨지고 (덮어써지고) 자식 메소드가 우선적으로 사용된다.

@Override 라는 어노테이션을 사용해 에러를 줄일 수 있다. (해당 어노테이션을 쓰면 정확히 오버라이드가 되어야만 오류가 나지 않는다.)

 

<규칙>

- 접근 제한을 더 강하게 오버라이딩 할 수 없음 (public -> private으로 변경 불가), 넓히는건 가능, 좁히는건 불가능!

- 부모 메소드의 선언부 (리턴타입, 메소드이름, 매개변수)와 동일해야 함

- 새로운 예외를 throws할 수 없다. (선언부가 똑같아야 하니까)

 

cf) 메소드 오버로딩

 

3. 타입 변환

1) 자동 형변환

		int a = 0;
		double b = a; // 자동 형변환
		Phone p = myPhone; // 자동형변환
		// 자식에서 추가된 메서드 실행안됨
		// p.internet(); -> Phone에는 internet이 없으니까 사용 불가
		
		// 자식에서 재정의된 메서드는 됨
		p.sendVoice("안녕"); // 나: 로 나옴

자식에서 추가된 메서드는 실행이 안되지만 자식에서 재정의된 메서드는 실행이 된다.

 

2) 강제 형변환

강제형변환의 조건: 자식 -> 부모 형변환된 객체만 가능!

		Phone p2 = new Phone();
		SmartPhone c2 = (SmartPhone)p2; // 강제 형변환 -> 오류
		SmartPhone c3 = (SmartPhone)p; // 강제형변환 -> 오류 안남

두 번째 줄을 실행하면 코드에서는 오류가 나지 않지만 실행시키면 아래와 같은 오류가 발생한다.

Exception in thread "main" java.lang.ClassCastException: class ch07.sec02.Phone cannot be cast to class ch07.sec02.SmartPhone (ch07.sec02.Phone and ch07.sec02.SmartPhone are in unnamed module of loader 'app')
at ch07.sec02.SmartPhoneExample.main(SmartPhoneExample.java:35)

하지만 세번째 줄처럼 실행하면 오류가 나지 않는다. 그 이유는 강제 형변환의 조건 때문이다. p는 앞서 부모로 한번 형변환이 된 적 있는 객체이다. 따라서 자식 -> 부모로 형변환된 객체이기 때문에 가능한 것이다.

 

<상속 요약정리>

- 부모클래스한테 물려 받는 것
- 다형성 (실행 코드는 하나지만 결과가 달라지는 것)
- 다형성을 구현하기 위해 필요한 것 (상속, 메서드 재정의)
- 메서드 재정의 (오버라이드) : 부모의 메서드를 자식이 다시 정의 (이름, 매개변수 동일)
- 형변환: 자식타입 -> 부모타입 자동 형변환 가능
             부모타입 -> 자식 타입 강제 형변환(자식 -> 부모 형변환된 상태) EX ) A -> Object -> A(가능), new object() -> A (불가능, 런타임에러)
- final (마지막)
  final 필드 (값 변경 불가)
  final 클래스 (상속 불가)
  final 메서드 (재정의 불가)
- 추상 (abstract)
  추상 클래스 객체 생성 불가 -> 상속받아서 객체 생성
  추상메서드: 선언부만 있는 메서드, 상속 클래스에서 반드시 재정의