상속

상속(Inheritance)

상속이란 기존의 클래스를 이용하여 새로운 클래스를 효율적으로 만들기 위한 기법이다. 하지만 상속에 대해서 이해하려면 상속에 대한 설명을 반대로 생각해볼 필요가 있다.

상속 형태

A라는 클래스가 B라는 클래스를 상속받으려면 다음과 같이 작성한다.

class B { }

class A extends B { }

상속의 필요성

휴대폰 매장에서 휴대폰을 관리하기 위한 프로그램을 만든다고 가정하고, 관리할 휴대폰을 분석해보니 다음 네 종류로 파악되었다.

상속을 배우지 않은 상태에서는 네 종류의 휴대폰 모두 각자의 클래스로 구현하여 필드, 메소드, 생성자 등을 작성하면 된다고 배웠기 때문에 다음과 같이 클래스를 작성할 것이다.

GalaxyNote10.java
public class GalaxyNote10 {
    String number;
    void call(){ /* 내용 생략 */ }
    void sms(){ /* 내용 생략 */ }
    void camera(){ /* 내용 생략 */ }
    void samsungPay(){ /* 내용 생략 */ }
}
GalaxyNote20.java
public class GalaxyNote20 {
    String number;
    void call(){ /* 내용 생략 */ }
    void sms(){ /* 내용 생략 */ }
    void camera(){ /* 내용 생략 */ }
    void samsungPay(){ /* 내용 생략 */ }
    void proVideo(){ /* 내용 생략 */ }
}
Iphone11.java
public class Iphone11 {
    String number;
    void call(){ /* 내용 생략 */ }
    void sms(){ /* 내용 생략 */ }
    void camera(){ /* 내용 생략 */ }
    void siri(){ /* 내용 생략 */ }
}
Iphone12.java
public class Iphone12 {
    String number;
    void call(){ /* 내용 생략 */ }
    void sms(){ /* 내용 생략 */ }
    void camera(){ /* 내용 생략 */ }
    void siri(){ /* 내용 생략 */ }
    void dualCamera(){ /* 내용 생략 */ }
}

객체도 다음과 같이 생성할 수 있다.

GalaxyNote10 note10 = new GalaxyNote10();
GalaxyNote20 note20 = new GalaxyNote20();
Iphone11 iphone11 = new Iphone11();
Iphone12 iphone12 = new Iphone12();

작성하면서 다음의 문제점이 느껴진다면 상속의 필요성을 인지한 것이다.

  1. 공통된 필드, 메소드 중복 작성

  2. 휴대폰이 더 늘어날 경우 관리가 어려움

  3. 시리즈 별 관리 어려움

상속 적용 사례

네 개의 클래스를 각각 따로 생각하는 것이 아니라 비슷한 특징을 가진 것들끼리 묶어보면 다음과 같다.

표시된 화면에서 갤럭시 노트 10갤럭시 노트 20은 삼성페이라는 동일한된 기능이 존재하며, 이는 갤럭시 휴대폰의 공통된 기능이라고 볼 수 있다.

또한 아이폰 11아이폰 12에서도 Siri음성인식 기능이 동일하게 존재하며, 이는 아이폰의 공통된 기능이라고 볼 수 있다.

좀 더 보기 쉽게 요약하여 계층별로 파악하면 다음과 같이 표현할 수 있다.

위와 같은 구조를 구현하려면 총 7개의 클래스가 필요하며, 3개의 클래스는 기존의 클래스와 다르게 공통된 내용들을 보관하기 위한 클래스의 역할을 수행해야 한다.

우선 휴대폰 역할을 수행할 수 있는 Phone이라는 클래스를 만들고 모든 휴대폰이 가지는 내용들을 구현한다.

Phone.java
public class Phone {
    String number;
    void call(){ /* 내용 생략 */ }
    void sms(){ /* 내용 생략 */ }
    void camera(){ /* 내용 생략 */ }
}

그리고 Phone의 기능들을 상속받는 갤럭시 노트 공통 클래스인 GalaxyNote를 구현한다. GalaxyNote 클래스에는 Phone 클래스를 상속받을 것임을 명시하고, 갤럭시 노트의 공통기능인 삼성페이를 구현한다.

GalaxyNote.java
public class GalaxyNote extends Phone {
    void samsungPay(){ /* 내용 생략 */ }
}

extends Phone 이라는 키워드를 통해 만들어놓은 Phone 클래스의 내용을 상속받아 사용할 수 있으므로 GalaxyNote 클래스에 보이는 메소드는 1개이지만 실제로는 멤버 변수 1개와 메소드 4개를 가진 것과 동일한 상태이다. 아이폰 공통 클래스인 Iphone 도 마찬가지로 구현한다.

Iphone.java
public class Iphone extends Phone {
    void siri(){ /* 내용 생략 */ }
}

Iphone 클래스 역시 마찬가지로 extends Phone 키워드를 통해 상속을 받아 총 1개의 멤버 변수와 4개의 멤버 메소드(3개 상속)를 가지게 된다.

갤럭시 노트 10, 갤럭시 노트 20, 아이폰 11, 아이폰 12는 각각 GalaxyNote, Iphone 클래스를 상속받아 만들 수 있으며 다음과 같다.

GalaxyNote10.java
public class GalaxyNote10 extends GalaxyNote {
    
}

객체 생성 구문은 상속 전과 동일하게 사용할 수 있다.

GalaxyNote10 note10 = new GalaxyNote10();
GalaxyNote20 note20 = new GalaxyNote20();
Iphone11 iphone11 = new Iphone11();
Iphone12 iphone12 = new Iphone12();

상속의 장점과 단점

상속을 이용하면 얻을 수 있는 장점과 단점이 명확하다.

  • 장점

    • 체계적인 구조를 갖추어 클래스 설계 가능

    • 중복 코드 감소

    • 신규 클래스 개발 속도 향상

  • 단점

    • 코드 분할로 인한 가독성 하락

    • 오류 추적이 어려

상속 시 주의사항

상속을 사용하려면 다음 내용들을 주의해야 한다.

  • 하위 클래스에 extends 키워드를 적어 상속받을 대상 클래스를 지정한다.

  • 상속받을 대상 클래스는 자기자신을 제외하고 단 하나만 지정할 수 있다.

  • 상속받을 경우 대상 클래스의 내용을 모두 가져오지만 접근이 불가한 항목은 사용할 수 없다.

상속 금지 설정

특정 클래스가 상속관계에서 사용되는 것을 원치 않는다면 금지 설정이 가능하다.

불변(final)

해당 문서의 데모5 을 통해 상속 금지 설정에 대해 확인할 수 있다.

Last updated