[Java 16] 자바 - 상속(1)
학습목표
- 상속의 사용방법을 정확히 알고 있다.
- 상속에서 부모 생성자를 명시적으로 호출하는 방법을 알고 있다.
상속이란
자바에서 부모 클래스의 멤버를 자식 클래스에게 물려주는 것을 상속(Inheritance)라고 합니다. 하지만 상속을 해도 부모의 모든 필드와 메소드를 물려받는 것은 아닙니다. 부모 클래스에서 private 접근 제한을 갖는 필드와 메소드는 상속 대상에서 제외됩니다. 또한, 부모와 자식 클래스가 다른 패키지에 존재한다면 default 접근 제한자를 갖는 필드와 메소드도 상속 대상에서 제외됩니다.
클래스 상속
자식 클래스 선언 시 어떤 부모 클래스를 상속 받을 것인지를 결정하고 다음과 같이 코드를 작성합니다.
class 자식클래스 extends 부모클래스 {
//필드
//생성자
//메소드
}
예제 1 다음의 코드 3개를 보며 상속의 쓰임에 대해 알아보겠습니다.
[CellPhone] => 부모 클래스
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("전화를 끊습니다."); }
}
[dmbCellPhone] => 자식 클래스
public class DmbCellPhone extends CellPhone { //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 방송 수신을 멈춥니다. ");
}
}
[DmbPhoneExample]
public class DmbPhoneExample{
public static void main(String[] args) {
DmbCellPhone dmb = new DmbCellPhone("자바폰", "검정", 10);
System.out.println("모델 : " + dmb.model);
System.out.println("색상 : " + dmb.color);
System.out.println("채널 : " + dmb.channel);
dmb.powerOn();
dmb.bell();
dmb.sendVoice("여보세요");
dmb.receiveVoice("안녕하세요! 저는 홍길동입니다.");
dmb.sendVoice("아~ 예 반갑습니다!");
dmb.hangUp();
dmb.turnOnDmb();
dmb.changeChannelDmb(11);
dmb.turnOffDmb();
}
}
부모 생성자 호출
상속을 수행하기 위해서는 부모 객체가 먼저 생성되고 자식 객체가 그 다음으로 생성됩니다. 아래의 코드를 보면 표면적으로는 DmbCellPhone 객체만 생성하는 것처럼 보이지만, 부모인 CellPhone 객체가 먼저 생성되고, 이를 상속받은 자식 객체 DmbCellPhone이 생성되는 것입니다.
DmbCellPhone dmb = new DmbCellPhone();
여기서 모든 객체는 클래스의 생성자를 호출해야만 생성이 가능하다고 배웠는데 부모 객체를 생성하기 위한 생성자는 어디서 호출한 것인지 의문이 생깁니다. 명시적으로 선언되지 않았다면 부모의 생성자가 자식 생성자의 맨 첫 줄에서 컴파일러가 호출합니다.
public DmbCellPhone() {
super(); //super()는 부모의 기본 생성자를 호출한다. public CellPhone() {}
}
이처럼 CellPhone의 생성자가 명시적으로 선언되지 않아도 컴파일러에 의해 기본 생성자가 만들어지게 됩니다. 만약 명시적으로 생성자를 호출하고 싶다면 다음과 같이 코드를 작성하면 됩니다.
자식클래스( 매개변수선언, ... ) {
super( 매개값, ...); //super(매개값)는 매개값의 타입과 일치하는 부모 생성자를 호출
...
}
super(매개값, …)는 매개값의 타입과 일치하는 부모 생성자를 호출하고 매개값의 타입과 일치하는 부모 생성자가 없을 경우 컴파일 오류가 발생합니다. 만약 부모 클래스에 기본 생성자는 없고 매개 변수만 있는 생성자만 있다면 자식 생성자에서 반드시 부모 생성자 호출을 위해 super(매개값, …)를 명시적으로 호출해야 합니다. super(매개값, …)는 반드시 자식 생성자 첫 줄에 위치해야 하고 그렇지 않은 경우 컴파일 오류가 발생합니다.
예제 2
[People] 부모 클래스
public class People {
public String name;
public String ssn;
public People(String name, String ssn) {
this.name = name;
this.ssn = ssn;
}
}
[Student] 자식 클래스
public class Student extends People{
public int studentNo;
public Student(String name, String ssn, int studentNo) {
super(name, ssn);
this.studentNo = studentNo;
}
}
[StudentMain] 자식 객체 이용
public class StudentMain {
public static void main(String[] args) {
Student student = new Student("박자바", "901231-1234556", 202312);
System.out.println("name : " + student.name);
System.out.println("ssn : " + student.ssn);
System.out.println("studentNo : " + student.studentNo);
}
}
실행결과
name : 박자바
ssn : 901231-1234556
studentNo : 202312
댓글남기기