본문 바로가기
프로그래밍언어/Java

07-1 상속

by 스꼬맹이브로 2021. 2. 25.
728x90
반응형
SMALL

상속(inheritance)은 부모 클래스의 멤버를 자식 클래스에게 물려주는 것을 말한다.

프로그램에서는 부모 클래스를 상위 클래스라고 부르고, 자식 클래스를 하위 클래스 또는 파생 클래스라고 한다.

 

상속은 이미 잘 개발된 클래스를 재사용해서 새로운 클래스를 만들기 때문에 중복되는 코드를 줄여준다.

 

<클래스 상속>

현실에서 상속은 부모가 자식을 선택해서 물려주지만, 프로그램에서는 자식이 부모를 선택한다.

자식 클래스를 선언할 때 어떤 부모 클래스를 상속받을 것인지 결정하고, 선택된 부모 클래스는 extends뒤에  기술한다.

class 자식클래스 extends 부모클래스 {
  //필드
  //생성자
  //메소드
}

예를 들어, Car클래스를 상속해서 SportsCar클래스를 설계하려면 다음과 같이 작성한다.

class SportsCar extends Car{

}

자바에서 상속의 특징은 다음과 같다.

  1. 여러 개의 부모 클래스를 상속할 수 없다. (extends 뒤에는 단 하나의 부모 클래스만 와야 한다.)
  2. 부모 클래스에서 private 접근 제한을 갖는 필드와 메소드는 상속 대상에서 제외된다.
    또한 다른 패키지에 존재한다면 default 접근 제한을 갖는 필드와 메소드도 상속 대상에서 제외된다.

*핸드폰(부모클래스)를 통해 dmb폰(자식클래스) 작성 예제

//핸드폰클래스(부모클래스)
public class CellPhone {
	//필드
	String model;
	String 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("전화를 끊습니다."); }
}
//dmb폰클래스(자식클래스)
public class DmbCellPhone extends CellPhone {
	//필드
	int channel;
	
	//생성자
	DmbCellPhone(String model, String color, int channel) {
		this.model = model;
		this.color = color;
		this.channel = channel;
	}

	//메소드
	void turnOnDmb() {
		System.out.println("채널 " + channel + "번 DMB 방송 수신을 시작합니다.");
	}	
	void changeChannelDmb(int channel) {
		this.channel = channel;
		System.out.println("채널 " + channel + "번으로 바꿉니다.");
	}
	void turnOffDmb() {
		System.out.println("DMB 방송 수신을 멈춥니다.");
	}	
}
public class DmbCellPhoneExample {
	public static void main(String[] args) {
		//DmbCellPhone 객체 생성
		DmbCellPhone dmbCellPhone = new DmbCellPhone("자바폰", "검정", 10);
		
		//CellPhone으로부터 상속 받은 필드
		System.out.println("모델: " + dmbCellPhone.model);
		System.out.println("색상: " + dmbCellPhone.color);
		
		//DmbCellPhone의 필드
		System.out.println("채널: " + dmbCellPhone.channel);
		
		//CellPhone으로부터 상속 받은 메소드 호출
		dmbCellPhone.powerOn();
		dmbCellPhone.bell();
		dmbCellPhone.sendVoice("여보세요");
		dmbCellPhone.receiveVoice("안녕하세요! 저는 홍길동인데요");
		dmbCellPhone.sendVoice("아~ 예 반갑습니다.");
		dmbCellPhone.hangUp();

		//DmbCellPhone의 메소드 호출
		dmbCellPhone.turnOnDmb();
		dmbCellPhone.changeChannelDmb(12);
		dmbCellPhone.turnOffDmb();
	}
}

결과 :

 

<부모 생성자 호출>

자식 객체를 생성하면, 부모 객ㅌ체가 먼저 생성되고 그 다음에 자식 객체가 생성된다.

DmbCellPhone dmbCellPhone = new DmbCellPhone();

이 코드는 DmbCellPhone 객체만 생성하는 것처럼 보이지만, 사실은 내부적으로 부모인 CellPhone 객체가 먼저 생성되고 자식 객체가 생성된 것이다.

 

이 과정을 메모리로 표현하면 다음과 같다.

모든 객체는 클래스의 생성자를 호출해야만 생성되며, 부모 생성자는 자식 생성자의 맨 첫 줄에서 호출된다.

직접 자식 생성자를 선언하고 명시적으로 부모 생성자를 호출하고 싶으면 다음과 같이 작성하면 된다.

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

여기서 super()는 부모의 기본 생성자를 호출하며, super(매개값, ...)는 매개값의 타입과 일치하는 부모 생성자를 호출한다. 만약 매개값의 타입과 일치하는 부모 생성자가 없을 경우 컴파일 에러가 발생한다.

 

<메소드 재정의>

부모 클래스의 모든 메소드가 자식 클래스에 맞게 설계되어 있다면 가장 이상적인 상속이지만, 어떤 메소드는 자식 클래스가 사용하기에 적합하지 않을 수도 있다. 이런 경우에 메소드를 다시 수정해서 사용하며, 메소드 재정의(오버라이딩:Overriding)이라고 한다.

 

▶ 메소드 재정의 방법

  1. 부모의 메소드와 동일한 시그니처(리턴 타입, 메소드 이름, 매개 변수 목록)를 가져야 한다.
  2. 접근 제한을 더 강하게 재정의할 수 없다.
  3. 새로운 예외(Exception)를 throws할 수 없다.(예외는 다음에 학습 예정!)

메소드가 재정의되었다면 부모 객체의 메소드는 숨겨지기 때문에, 자식 객체에서 메소드를 호출하면 재정의된 자식 메소드가 호출된다.

 

▶ 부모 메소드 호출

자식 클래스 내부에서 재정의된 부모 클래스의 메소드를 호출해야 하는 상황이 발생한다면 명시적으로 super 키워드를 붙여서 부모 메소드를 호출할 수 있다.

super.부모메소드();

 

<final 클래스와 final 메소드>

final 키워드는 클래스, 필드, 메소드를 선언할 대 사용할 수 있는데, 해당 선언이 최종 상태이고 결코 수정될 수 없음을 뜻한다.

 

상속할 수 없는 final 클래스

클래스를 선언할 때 final 키워드를 class 앞에 붙이면 이 클래스는 최종적인 클래스이므로 상속할 수 없는 클래스가 된다. 즉, final 클래스는 자식 클래스를 만들 수 없다.

 

final클래스 선언 방법은 다음과 같다.

public final class 클래스 { ... }

final 클래스의 대표적인 예는 자바 표준 API에서 제공하는 String 클래스이다. String클래스는 final클래스이기 때문에 자식 클래스를 만들 수 없다.

 

재정의할 수 없는 final 메소드

메소드를 선언할 때 final 키워드를 붙이면 최종적인 메소드이므로 재정의할 수 없는 메소드가 된다. 즉, 부모 클래스를 상속해서 자식 클래스를 선언할 때 부모 클래스에 선언된 final 메소드는 자식 클래스에서 재정의할 수 없다.

 

final 메소드 선언 방법은 다음과 같다.

public final 리턴타입 메소드( [매개변수, ...]){...}

 

728x90
반응형
LIST

'프로그래밍언어 > Java' 카테고리의 다른 글

07-3 추상 클래스  (0) 2021.04.28
07-2 타입 변환과 다형성  (0) 2021.03.09
06-6 패키지와 접근 제한자  (0) 2021.02.23
06-5 인스턴스 멤버와 정적 멤버  (0) 2021.02.17
06-4 메소드  (0) 2021.02.15