Java 상속 #1

jjinny_0609·2023년 2월 15일
0

Java

목록 보기
19/31

상속

상속(Inheritance)

부모가 자식에게 물려주는 행위
부모 클래스의 멤버를 자식 클래스에게 물려주는 행위
잘 개발되어 있는 클래스를 재사용해서 새로운 클래스를 만들때 중복코드를 최소화 시켜준다.

클래스 상속

속성
class 자식클래스 extends 부모클래스{
      //필드
      //생성자
      //메서드
}
자식 클래스를 선언할 때 어떤 부모 클래스를 상속받을 것인지 결정하고, 선택된 부모 클래스는 다음과 같이
extends 뒤에 기술한다.

규칙
① 여러 개의 부모 클래스를 상속할 수 없다.
② 부모 클래스에서 private 접근 제한을 갖는 필드와 메소드는 상속 대상에서 제외됩니다.
그리고 부모 클래스와 자식 클래스가 다른 패키지에 존재한다면 default 접근 제한을 갖는
필드와 메소드도 상속 대상에서 제외됩니다.

예제

-------------------------------------------------------------------------------
파일명 CellPhone.java
package ch07;

public class CellPhone {
	// 필드
	// 모델
	String model;
	// 색상
	String color;
	// 생성자
	/*CellPhone(String model, String color){
		this.model = model;
		this.color = color;
	}*/
		
	// 메서드
	// 전원을 켠다.
	void powerOn() {System.out.println("전원을 켭니다.");}
	// 전원을 끈다.
	void powerOff() {System.out.println("전원을 끕니다.");}
	// 벨을 울림
	void bell() {System.out.println("벨을 울립니다.");}
	// 메시지를 송신한다.
	void sendVoice(String message) {System.out.println("자기 : " + message);}
	// 메시지를 수신한다.
	void receiveVoice(String message) {System.out.println("상대방 : " + message);}
	// 전화를 끊는다.
	void hangup() {System.out.println("전화를 끊습니다.");}
	//static이 없다 -> 인스턴스 메서드
}
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
파일명 : DmbCellPhone.java
package ch07;
// 통화 + dmb기능까지 장착한 폰
public class DmbCellPhone extends CellPhone {
	// 필드
	// 모델(CellPhone클래스에서 상속받았으므로 따로 선언안함.)
	// 색상(CellPhone클래스에서 상속받았으므로 따로 선언안함.)
	// 채널
	int channel;
	// 생성자(매개변수가 3개인 생성자) 선언

	DmbCellPhone(String model, String color, int channel){
		this.model = model;
		this.color = color;
		this.channel = channel;
	}
	// DMB 관련 기능
	void turnOnDmb() {
		System.out.println("채널 " + channel + "번 방송 수신을 시작합니다.");
	}
	void changeChannelDmn(int channel) {
		this.channel = channel;
		System.out.println("채널 " + channel + "번으로 바꿉니다.");
	}
	void turnOffDmb() {
		System.out.println("DMB 방송 수신을 멈춥니다.");
	}
}
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
파일명 : DmbCellPhoneExmaple.java
package ch07;

public class DmbCellPhoneExample {
	public static void main(String[] args) {
//	CellPhone dcp = new CellPhone();
	// CellPhone cp = new CellPhone("자바폰", "블랙");
	DmbCellPhone dcp = new DmbCellPhone("자바폰", "검정", 10);

	// CellPhone 클래스로부터 상속받은 필드
	System.out.println("모델 : " + dcp.model);
	System.out.println("색상 : " + dcp.color);
	
	//DmbCellPhone 클래스의 필드
	System.out.println("채널 : " + dcp.channel);
	
	// CellPhone 클래스로부터 상속받은 메소드 호출
	dcp.powerOn();
	dcp.bell();
	dcp.sendVoice("여보세요");
	dcp.receiveVoice("안녕하세요 저는 홍길동인데요.");
	dcp.sendVoice("아~ 예 반갑습니다.");
	dcp.hangup();
	
	// DmbCellPone클래스로 부터 메소드 호출
	dcp.turnOnDmb();
	dcp.changeChannelDmn(12);
	dcp.turnOffDmb();
	}
}

-------------------------------------------------------------------------------

예제 출력결과


부모 생성자 호출

현실에서 부모 없는 자식이 있을 수 없듯이 자바에서도 자식 객체를 생성하면,
부모 객체가 먼저 생성되고 그 다음에 자식 객체가 생성됩니다.
-> 모든 객체는 클래스의 생성자를 호출해야만 생성되며, 부모 생성자는 자식 생성자의 맨 첫줄에서 호출됩니다.
super();가 없으면 컴파일러는 자동으로 기본 생성자를 호출합니다.

명시적으로 부모 생성자를 호출하고 싶다면
super(); -> 기본 생성자를 호출

super( 매개값, ... );
super()는 자식 생성자 첫줄에 위치해야함


메소드 재정의(메소드 오버라이딩; Overriding)

상속된 일부 메소드는 자식 클래스에서 다시 수정해서 사용해아한다.
이런 경우 메소드 재정의 기능을 이용한다.


메소드 재정의 방법

  • 규칙
    주의 : 선언부를 바꾸는게 아니라 괄호 안에 있는 내용을 바꾸는것.
    부모의 메소드와 동일한 시그니처(리턴 타입, 메소드 이름, 매개 변수 목록)를 가져야 합니다.
    접근 제한을 더 강하게 재정의 할 수 없습니다.
    새로운 예외(Exception)를 throws 할 수 없습니다(예외는 10장에서 학습합니다.)

'접근 제한을 더 강하게 재정의 할 수 없다'
부모가 public 접근 제한을 가지고 있는데 default 나 private 접근 제한으로 수정 할 수 없다.
단, 반대 경우는 가능하다. 부모 메소드가 default 접근 제한을 가지면 재정의 하는 자식 메소드는
default 또는 public 접근 제한을 가질 수 있습니다.

부모가 default 자식이 public -> 가능


부모 메소드 호출

자식 클래스에서 부모 클래스의 메소드를 재정의하게 되면, 부모 클래스의 메소드는 숨겨지고 재정의 된 자식 메소드만 사용됩니다.
그러나 자식 클래스 내부에서 재정의된 부모 클래스의 메소드를 호출해야
하는 상황이 발생한다면 명시적으로 super 키워드를 붙여서 부모 메소드를 호출 할 수 있습니다.
super.부모메소드();


final 클래스와 final 메소드

클래스와 메소드를 선언 할때 final 키워드가 지정되면 상속과 관련이 있다는 의미다.

상속할 수 없는 final 클래스

클래스를 선언할 떄 final 키워드를 class앞에 붙이면 이 클래스는 최종적인 클래스이므로 상속할 수 없는
클래스가 됩니다. 즉, final 클래스는 부모 클래스가 될 수 없어 자식 클래스를 만들 수 없다는 것이다.

public final class 클래스 { ... }


The type VeryImportantPerson cannot subclass the final class Member
(VeryImportantPerson 유형은 최종 클래스 구성원을 하위 클래스로 분류할 수 없습니다)
-> final을 상속해서 사용할 수 없음.


재정의할 수 없는 final 메서드

메서드를 선언할 때 final 키워드를 붙이면 이 메서드는 재정의 할 수 없는 메서드라는 뜻입니다.
즉, 부모 클래스를 상속해서 자식 클래스를 선언할 때 부모클래스에 선언된 final 메서드는 자식 클래스에서 재정의 할 수 없다는 것입니다.
public final 리턴타입 메서드( [매개변수, ...] ) { ... }


protected 접근 제한자

복습

public < protected < (default) < private

public : 접근 제한이 없다.

protected : 같은 패키지에 있는 클래스는 접근 가능. 다른 패키지에 있는 패키지는 접근 불가능

  • 상속을 하면 다른 패키지에 있는 클래스는 접근 가능 *

(default) : 같은 패키지에 있는 클래스는 접근 가능 다른 패키지에 있는 패키지는 접근 불가능

  • 상속을 해도 다른 패키지에 있는 클래스 접근 불가능 *

private : 외부에서 접근이 불가. (같은 클래스 내부에서만 접근이 가능)


protected 접근 제한자 예제


1번 패키지에 있는 A에 default 제한자로 바꾸면 2번 패키지에 있는 super();에 오류가 생김
The constructor A() is not visible
(생성자 A()이(가) 표시되지 않습니다)

마무리 정리

  • 상속 : 부모 클래스의 필드 메소드를 자식 클래스에서 사용할 수 있도록 합니다. extends 사용
  • 메소드 재정의 : 부모 메소드를 자식 클래스에서 다시 정의하는 것을 말합니다.
  • final 클래스 : final 키워드로 선언된 클래스는 부모 클래스로 사용할 수 없는 final 클래스 입니다.
  • final 메소드 : final 키워드로 선언된 메소드는 자식 클래스에서 재정의할 수 없는 final 메소드입니다.
profile
뉴비 개발자 입니다. velog 주소 : https://velog.io/@jjinny_0609 Github 주소 :

0개의 댓글