Java

[Java] 상속

콩스프 2022. 12. 11. 23:00

상속의 개념

  • 현실에서 상속(Inheritance) : 부모가 자식에게 물려주는 행위
  • 자식은 상속을 통해서 부모가 물려준 것을 자연스럽게 (no cost) 이용할 수 있음
  • 객체 지향 프로그램에서도 부모 클래스의 멤버를 자식 클레스에게 물려줄 수 있음
  • 프로그램에서는 부모 클래스상위 클래스, 자식 클래스하위클래스 / 파생 클래스 라고 부름

 

  • 상속은 이미 잘 개발된 클래스재사용해서 새로운 클래스를 만들기 때문에 코드의 중복을 줄임

 

 

  • field1, fiedl2, method1(), method2() 를 가지는 클래스를 작성한다고 할 때
          ① 4개를 모두 처음부터 작성하는 것
          ② field1과 method1()을 가지고 있는 클래스가 있다면 이를 상속하고 field2와 method2()만 추가 작성 


  • ① 보다 ②가 효율적이고 개발시간을 절약시켜줌

 

B b = new B();

//A로 부터 물려받은 필드와 메소드
b.field1 = 10;
b.method1();

//B가 추가한 필드와 메소드
b.field2 = "홍길동";
b.method2();
  • 실제로 B클래스 객체를 생성해서 사용할 때 마치 B가 field1과 method1()을 가지고 있는 것 처럼 보임

 

  • 상속을 해도 부모 클래스의 모든 필드와 메소드들을 물려받는 것은 아님
    • 부모 클래스에서 private 접근 제한을 갖는 필드와 메소드상속 대상에서 제외
    • 부모 클래스자식 클래스가 다른 패키지에 존재한다면 default 접근 제한을 갖는 필드와 메소드상속 대상에서 제외
  • 이 이외의 경우는 모두 상속의 대상

  • 상속을 이용하면 클래스의 수정을 최소화시킬 수 있음
    • 부모 클래스의 수정으로 모든 자식 클래스들의 수정 효과를 가져옴 ➡ 유지 보수 시간을 최소화 
      EX) 클래스 A와 이를 상속받는 클래스 B, C
             클래스 A의 필드와 메소드를 수정함으로써 B, C를 수정하지 않아도 수정된 A의 필드와 메소드를 이용할 수 있음

 

 

클래스 상속

  • 현실에서 상속 : 부모가 자식을 선택해서 물려줌 ↔ 프로그램에서의 상속 : 자식이 부모를 선택
  • 자식 클래스를 선언할 때 어떤 부모 클래스를 상속받을 것인지를 결정
  • 부모 클래스는 extends 뒤에 기술
class 자식클래스 extends 부모클래스 {	
    //필드
    //생성자
    //메소드
}

 

 

상속을 받는 자식 클래스의 선언 EX)

class SportsCar extends Car {
	...
}
  • Car 클래스를 상속받는 SportsCar 클래스

 

💡 주의 : 다른 언어와 달리 자바는 다중 상속을 허용하지 않음

  • 여러 개의 부모 클래스를 상속할 수 없음
  • extends 뒤에는 단 하나의 부모 클래스만 와야 함
class 자식클래스 extends 부모클래스1, 부모클래스2(X) { //다중 상속 지원X
	...
}

 

 

상속 EX)

  • 핸드폰 (CellPhone) 클래스를 상속해서 DMB폰 (DmbCellPhone) 클래스를 작성한 예제
//[CellPhone.java - 부모클래스]
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.java - 자식클래스]
public class DmbCellPhone extends CellPhone {
    //필드
    int channel;
    
    //생성자
    DmbCellPhone(String model, String color, int channel) {
    	this.model = model; //CellPhone 으로부터 상속받은 필드
        this.color = color; //CellPhone 으로부터 상속받은 필드
        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 InheritancePractice {
	public static void main(String[] args) {   	
        //DmbCellPhone 객체 생성
        DmbCellPhone dmbCellPhone = new DmbCellPhone("I폰", "실버", 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();
    }
}

실행 결과)