> For the complete documentation index, see [llms.txt](https://docs.sysout.co.kr/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sysout.co.kr/base-language/java/advanced/inheritance.md).

# 상속

## 상속(Inheritance)

{% embed url="<https://www.youtube.com/watch?v=M3zlc6jiB5o>" %}

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

### 상속 형태

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

```java
class B { }

class A extends B { }
```

### 상속의 필요성

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

![관리해야할 휴대폰 종류와 구성요소(빨강 : 필드 , 파랑 : 메소드)](/files/-MeSPmKXuGBzqsTS1REd)

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

{% code title="GalaxyNote10.java" %}

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

{% endcode %}

{% code title="GalaxyNote20.java" %}

```java
public class GalaxyNote20 {
    String number;
    void call(){ /* 내용 생략 */ }
    void sms(){ /* 내용 생략 */ }
    void camera(){ /* 내용 생략 */ }
    void samsungPay(){ /* 내용 생략 */ }
    void proVideo(){ /* 내용 생략 */ }
}
```

{% endcode %}

{% code title="Iphone11.java" %}

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

{% endcode %}

{% code title="Iphone12.java" %}

```java
public class Iphone12 {
    String number;
    void call(){ /* 내용 생략 */ }
    void sms(){ /* 내용 생략 */ }
    void camera(){ /* 내용 생략 */ }
    void siri(){ /* 내용 생략 */ }
    void dualCamera(){ /* 내용 생략 */ }
}
```

{% endcode %}

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

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

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

1. 공통된 필드, 메소드 중복 작성
2. 휴대폰이 더 늘어날 경우 관리가 어려움
3. 시리즈 별  관리 어려움

### 상속 적용 사례

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

![클래스 구성요소 중복이 발생한다.](/files/-MeSTCdZQV1a8IVxeEr3)

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

![갤럭시 휴대폰의 고유 기능](/files/-MeSUuDyvtSOgeV9hvdP)

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

![아이폰의 고유 기능](/files/-MeSV9PYGPimEDvLyKFm)

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

![네 개의 클래스를 공통된 기능별로 계층화하여 표현](/files/-MeSUSVgtB54dCF9epq0)

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

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

{% code title="Phone.java" %}

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

{% endcode %}

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

{% code title="GalaxyNote.java" %}

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

{% endcode %}

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

{% code title="Iphone.java" %}

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

{% endcode %}

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

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

{% tabs %}
{% tab title="GalaxyNote10" %}
{% code title="GalaxyNote10.java" %}

```java
public class GalaxyNote10 extends GalaxyNote {
    
}
```

{% endcode %}
{% endtab %}

{% tab title="GalaxyNote20" %}
{% code title="GalaxyNote20.java" %}

```java
public class GalaxyNote20 extends GalaxyNote {
    public void proVideo() { /* 내용 생략 */ }
}
```

{% endcode %}
{% endtab %}

{% tab title="Iphone11" %}
{% code title="Iphone11.java" %}

```java
public class Iphone11 extends Iphone {

}
```

{% endcode %}
{% endtab %}

{% tab title="Iphone12" %}
{% code title="Iphone12.java" %}

```java
public class Iphone12 extends Iphone {
    public void dualCamera(){ /* 내용 생략 */ }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

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

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

### 상속의 장점과 단점

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

* 장점
  * 체계적인 구조를 갖추어 클래스 설계 가능
  * 중복 코드 감소
  * 신규 클래스 개발 속도 향상
* 단점&#x20;
  * 코드 분할로 인한 가독성 하락
  * 오류 추적이 어려

### **상속 시 주의사항**

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

* 하위 클래스에 extends 키워드를 적어 상속받을 대상 클래스를 지정한다.
* 상속받을 대상 클래스는 자기자신을 제외하고 단 하나만 지정할 수 있다.
* 상속받을 경우 대상 클래스의 내용을 모두 가져오지만 접근이 불가한 항목은 사용할 수 없다.

### 상속 금지 설정

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

{% content-ref url="/pages/-MeOLF3hNkaZoVWWbN87" %}
[불변(final)](/base-language/java/advanced/final.md)
{% endcontent-ref %}

해당 문서의 [데모5 ](/base-language/java/advanced/final.md#5)을 통해 상속 금지 설정에 대해 확인할 수 있다.
