부모가 자식에게 물려주는 행위
부모 클래스의 멤버를 자식 클래스에게 물려주는 행위
잘 개발되어 있는 클래스를 재사용해서 새로운 클래스를 만들때 중복코드를 최소화 시켜준다.
속성
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()는 자식 생성자 첫줄에 위치해야함
상속된 일부 메소드는 자식 클래스에서 다시 수정해서 사용해아한다.
이런 경우 메소드 재정의 기능을 이용한다.
'접근 제한을 더 강하게 재정의 할 수 없다'
부모가 public 접근 제한을 가지고 있는데 default 나 private 접근 제한으로 수정 할 수 없다.
단, 반대 경우는 가능하다. 부모 메소드가 default 접근 제한을 가지면 재정의 하는 자식 메소드는
default 또는 public 접근 제한을 가질 수 있습니다.
부모가 default 자식이 public -> 가능
자식 클래스에서 부모 클래스의 메소드를 재정의하게 되면, 부모 클래스의 메소드는 숨겨지고 재정의 된 자식 메소드만 사용됩니다.
그러나 자식 클래스 내부에서 재정의된 부모 클래스의 메소드를 호출해야
하는 상황이 발생한다면 명시적으로 super 키워드를 붙여서 부모 메소드를 호출 할 수 있습니다.
super.부모메소드();
클래스와 메소드를 선언 할때 final 키워드가 지정되면 상속과 관련이 있다는 의미다.
클래스를 선언할 떄 final 키워드를 class앞에 붙이면 이 클래스는 최종적인 클래스이므로 상속할 수 없는
클래스가 됩니다. 즉, final 클래스는 부모 클래스가 될 수 없어 자식 클래스를 만들 수 없다는 것이다.
public final class 클래스 { ... }
The type VeryImportantPerson cannot subclass the final class Member
(VeryImportantPerson 유형은 최종 클래스 구성원을 하위 클래스로 분류할 수 없습니다)
-> final을 상속해서 사용할 수 없음.
메서드를 선언할 때 final 키워드를 붙이면 이 메서드는 재정의 할 수 없는 메서드라는 뜻입니다.
즉, 부모 클래스를 상속해서 자식 클래스를 선언할 때 부모클래스에 선언된 final 메서드는 자식 클래스에서 재정의 할 수 없다는 것입니다.
public final 리턴타입 메서드( [매개변수, ...] ) { ... }
복습
public < protected < (default) < private
public : 접근 제한이 없다.
protected : 같은 패키지에 있는 클래스는 접근 가능. 다른 패키지에 있는 패키지는 접근 불가능
(default) : 같은 패키지에 있는 클래스는 접근 가능 다른 패키지에 있는 패키지는 접근 불가능
private : 외부에서 접근이 불가. (같은 클래스 내부에서만 접근이 가능)
protected 접근 제한자 예제
1번 패키지에 있는 A에 default 제한자로 바꾸면 2번 패키지에 있는 super();에 오류가 생김
The constructor A() is not visible
(생성자 A()이(가) 표시되지 않습니다)