최신판 |
당신의 편집 |
1번째 줄: |
1번째 줄: |
− | {{다른뜻|상속}}
| + | '''상속'''(相續, inheritance)은 [[객체 지향 프로그래밍]]에서 크게 3요소로 꼽는 [[캡슐화]], 상속, [[다형성]] 세 가지 중 상속을 일컫는다. [[자바]]에서는 계승, 확장이라는 단어로 사용된다. |
− | | |
− | '''상속'''(相續, inheritance)은 [[객체 지향 프로그래밍]](OOP)에서 자손 클래스가 조상 클래스의 기능을 그대로 이어받아서 [[재사용]]하는 것을 말한다. [[자바]]에서는 계승, 확장이라는 단어로 사용된다.<ref name="나무위키">나무위키, 〈[https://namu.wiki/w/%EC%83%81%EC%86%8D(%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D)#s-2.3.1 상속(프로그래밍]〉, 《나무위키》</ref> | |
| | | |
| == 개요 == | | == 개요 == |
− | [[객체 지향 프로그래밍]]의 3요소는 [[캡슐화]], 상속, [[다형성]]이다. 클래스로 객체가 정의되는 고전 상속에서, 클래스는 기반 클래스, 수퍼클래스, 또는 부모 클래스 등의 기존의 클래스로부터 속성과 동작을 상속받을 수 있다. 그 결과로 생기는 클래스를 파생 클래스, 서브클래스, 또는 자식 클래스라고 한다. 상속을 통한 클래스들의 관계는 계층을 형성한다. | + | [[객체 지향 프로그래밍]](OOP)에서 자손 클래스가 조상 클래스의 기능을 그대로 이어받아서 재사용하는 것을 상속이라 말한다. 클래스로 객체가 정의되는 고전 상속에서, 클래스는 기반 클래스, 수퍼클래스, 또는 부모 클래스 등의 기존의 클래스로부터 속성과 동작을 상속받을 수 있다. 그 결과로 생기는 클래스를 파생 클래스, 서브클래스, 또는 자식 클래스라고 한다. 상속을 통한 클래스들의 관계는 계층을 형성한다. |
| :{|class=wikitable width=700 style="background-color:#ffffee" | | :{|class=wikitable width=700 style="background-color:#ffffee" |
| |+ 상속 명칭 구분 | | |+ 상속 명칭 구분 |
23번째 줄: |
21번째 줄: |
| | | |
| ==특징== | | ==특징== |
− | 상속을 통해서 클래스를 작성하면, 보다 적은 양의 코드로 새로운 [[클래스]]를 작성할 수 있고 코드를 공통적으로 관리할 수 있기 때문에 코드의 추가 및 변경이 매우 용이하다. 이러한 특징은 코드의 재사용성을 높이고 코드의 중복을 제거하여 프로그램의 생산성과 유지보수에 크게 기여한다. 그리고 객체의 다형성을 구현 할 수 있다는 효과를 가지고 있다. | + | 상속을 통해서 클래스를 작성하면, 보다 적은 양의 코드로 새로운 클래스를 작성할 수 있고 코드를 공통적으로 관리할 수 있기 때문에 코드의 추가 및 변경이 매우 용이하다. 이러한 특징은 코드의 재사용성을 높이고 코드의 중복을 제거하여 프로그램의 생산성과 유지보수에 크게 기여한다. 그리고 객체의 다형성4을 구현 할 수 있다는 효과를 가지고 있다. |
− | 즉, 하위 객체에서 상위객체의 [[필드]]와 [[메소드]]를 따로 또 만들어서 사용할 필요가 없으며 상위 객체의 메소드에 문제가 있을 경우 상위 객체에서의 수정으로 인해 하위객체에서 문제가 있었던 메소드를 따로 수정할 필요없이 메소드를 사용할 수 있다.<ref name="Web Club">재희 jaiyah, 〈[https://webclub.tistory.com/169 객체 지향 프로그래밍의 상속과 다형성]〉, 《Web Club》</ref> | + | 즉, 하위 객체에서 상위객체의 필드와 메소드를 따로 또 만들어서 사용할 필요가 없으며 상위 객체의 메소드에 문제가 있을 경우 상위 객체에서의 수정으로 인해 하위객체에서 문제가 있었던 메소드를 따로 수정할 필요없이 메소드를 사용할 수 있다.<ref name="Web Club">재희 jaiyah, 〈[https://webclub.tistory.com/169 객체 지향 프로그래밍의 상속과 다형성]〉, 《Web Club》</ref> |
| + | |
| + | 상속은 부모클래스로부터 멤버변수, 메서드르 상속 받는 것은 가능하지만 생성자는 상속이 불가능하다. 또한 접근권한자가 private로 선언된 멤버변수와 메서드는 상속이 불가능하다. |
| | | |
| ===장점=== | | ===장점=== |
− | 객체 지향의 특징 중 첫번째 상속은 객체를 만들어 놓고 언제든지 다시 쓸 수 있다는 장점을 가지고 있다. 이 상속의 특징때문에 이미 만들어 놓은 상위 객체를 재사용해서 하위 객체를 쉽고 빠르게 만들수 있다. 그러므로 잘 만들어 놓은 객체만 있다면 고생할 필요가 없고 수정을 할때도 상위 객체를 수정해주면 상속받은 모든 하위 객체가 수정이 되므로 유지보수가 쉽다. <ref name="Ara Blog">Ara Blog, 〈[https://hunit.tistory.com/152 자바(JAVA) 객체지향 특징 상속/캡슐화/다형성]〉, 《개인블로그》, 2015-10-29</ref> | + | 객체 지향의 특징중 첫번째 상속은 객체를 만들어 놓고 언제든지 다시 쓸 수 있다는 장점을 가지고 있다. 이 상속의 특징때문에 이미 만들어 놓은 상위 객체를 재사용해서 하위 객체를 쉽고 빠르게 만들수 있다. 그러므로 잘 만들어 놓은 객체만 있다면 고생할 필요가 없고 수정을 할때도 상위객체를 수정해주면 상속받은 모든 하위 객체가 수정이 되므로 유지보수가 쉽다. <ref name="Ara Blog">Ara Blog, 〈[https://hunit.tistory.com/152 자바(JAVA) 객체지향 특징 상속/캡슐화/다형성]〉, 《개인블로그》, 2015-10-29</ref> |
| | | |
| ===단점=== | | ===단점=== |
94번째 줄: |
94번째 줄: |
| class 부모클래스 extends 조상클래스 { 내용 } | | class 부모클래스 extends 조상클래스 { 내용 } |
| class 자식클래스1 extends 부모클래스 { 내용 } // 가능 | | class 자식클래스1 extends 부모클래스 { 내용 } // 가능 |
− |
| |
− | =====상속 제외=====
| |
− | #상속은 부모클래스로부터 멤버변수, 메소드르 상속 받는 것은 가능하지만 [[생성자]]는 상속이 불가능하다.
| |
− | #접근권한자가 private로 선언된 멤버변수와 메서드는 상속이 불가능하다.
| |
− | #부모클래스와 자식클래스가 다른 패키지에 존재한다면 default 접근 권한을 갖는 메소드는 상속이 불가능하다.<ref name="thisisjava">신용권, 〈[https://www.hanbit.co.kr/store/books/look.php?p_code=B1460673937 이것이 자바다]〉, 《한빛출판네트워크》, 2015-01-06</ref>
| |
− |
| |
− | =====부모생성자 호출<ref name="thisisjava"></ref>=====
| |
− | [[파일:Extends_super.jpg|200픽셀|섬네일|오른쪽|자식 객체 생성]]
| |
− | 자식 객체 생성은 부모 객체가 생성된 후 자식 객체를 생성한다.
| |
− | 자식생성자가 부모생성자를 명시적으로 선언하지 않았다면 컴파일러가 생성하여 자식생성자의 맨 첫줄에서 호출한다.
| |
− | 부모생성자의 호출방법은 자식생성자 맨 첫 줄에 super() 키워드를 사용한다.
| |
− | 만약 매개변수가 있는 부모생성자일 경우 반드시 명시적으로 선언해야 한다.
| |
− | public class 자식클래스 {
| |
− | public 자식생성자() {
| |
− | super(); //부모클래스의 부모생성자 호출
| |
− | }
| |
− |
| |
− | ====인터페이스====
| |
− | 자바에서는 다중상속이 불가능하다. 하지만 인터페이스를 사용한다면 다중상속이 가능하다. [[인터페이스]]는 일종의 [[추상클래스]]이며 클래스처럼 메소드를 가질 수 있지만 기능을 구현할 수 없다. 그리고 멤버변수도 가질 수 없으며 상수만 가능하다.
| |
− |
| |
− | extends를 이용한 클래스 상속은 하나만 되고 두개 이상은 인터페이스만 가능하다. 인터페이스를 implements 하는 것은 상속이 아니라 구현한다고 할 수 있으며, 두 개 이상의 구현 가능한 인터페이스를 콤마(,)로 구분해서 추가하면 된다.
| |
− |
| |
− | class Animals implements IBird, IFlay {
| |
− |
| |
− | @Override
| |
− | public void eat() {
| |
− | // TODO Auto-generated method stub
| |
− | }
| |
− |
| |
− | @Override
| |
− | public void travel() {
| |
− | // TODO Auto-generated method stub
| |
− | }
| |
− | }
| |
− | 위 소스와 같이 인터페이스에서 구현해야 할 함수는 클래스에서 필히 추가해야한다.<ref name="자바다중상속">녹두장군 - 상상을 현실로, 〈[https://mainia.tistory.com/2139 자바 다중상속 인터페이스 다루는 방법]〉, 《개인블로그》, 2015</ref>
| |
| | | |
| ====C++ 상속==== | | ====C++ 상속==== |
− | [[C++]]의 경우 private 상속, protected 상속, public 상속이 있다. private는 외부에서 접근이 불가능하며, protected는 외부에서 접근이 불가능하나 파생 클래스에서는 접근이 가능하고, public은 어디서나 접근이 가능하다. 이전에 본 상속들은 모두 public 상속이다.<ref name="C++상속">끝나지않는 프로그래밍 일기, 〈[https://blog.hexabrain.net/173 C++ 강좌 12편. 상속(Inheritance)]〉, 《개인블로그》, 2012-11-12</ref>
| + | C++의 경우 private 상속, protected 상속, public 상속이 있다. private는 외부에서 접근이 불가능하며, protected는 외부에서 접근이 불가능하나 파생 클래스에서는 접근이 가능하고, public은 어디서나 접근이 가능하다. 이전에 본 상속들은 모두 public 상속이다. |
− | | |
− | :{|width=80% border=1
| |
− | |-
| |
− | !align=center style="background-color:#87AFEB;" |상속
| |
− | !align=center style="background-color:#87AFEB;" |외부 접근
| |
− | !align=center style="background-color:#87AFEB;" |파생 클래스 접근
| |
− | |-
| |
− | |align=center |private 상속
| |
− | |align=center |X
| |
− | |align=center |X
| |
− | |-
| |
− | |align=center|protected 상속
| |
− | |align=center |X
| |
− | |align=center |O
| |
− | |-
| |
− | |align=center |public 상속
| |
− | |align=center |O
| |
− | |align=center |O
| |
− | |}
| |
− | | |
− | =====private 상속=====
| |
− | private 상속을 하게되면 private 제한자보다 접근 범위가 넓은 멤버는 모두 private 제한자로 바꾸어 상속을 하게 된다.
| |
− | class Parent {
| |
− | private:
| |
− | int num1;
| |
− | public:
| |
− | int num2;
| |
− | protected:
| |
− | int num3;
| |
− | };
| |
− |
| |
− | class Base : private Parent { };
| |
− |
| |
− | int main()
| |
− | {
| |
− | Base base;
| |
− |
| |
− | cout << base.num1 << endl; // error!
| |
− | cout << base.num2 << endl; // error!
| |
− | cout << base.num3 << endl; // error!
| |
− | return 0;
| |
− | }
| |
− | | |
− | 즉, 위와 같이 코드를 작성하면 에러가 생기게 되는데 private보다 접근 범위가 넓은 public, protected 멤버들은 전부 private로 바꾸어서 넘어와 버렸기 때문에 class Parent의 num2와 num3가 private로 변환되어 선언을 할 수 없게 되는 것이다.<ref name="C++상속">끝나지않는 프로그래밍 일기, 〈[https://blog.hexabrain.net/173 C++ 강좌 12편. 상속(Inheritance)]〉, 《개인블로그》, 2012-11-12</ref>
| |
− | | |
− | =====protected 상속=====
| |
− | protected 상속은 protected 제한자 보다 접근 범위가 넓은 멤버는 모두 protected 제한자로 바꾸어 상속한다.
| |
− | class Parent {
| |
− | private:
| |
− | int num1;
| |
− | public:
| |
− | int num2;
| |
− | protected:
| |
− | int num3;
| |
− | };
| |
− |
| |
− | class Base : protected Parent { };
| |
− | int main() {
| |
− |
| |
− | Base base;
| |
− |
| |
− | cout << base.num1 << endl; // error!
| |
− | cout << base.num2 << endl; // error!
| |
− | cout << base.num3 << endl; // error!
| |
− |
| |
− | return 0;
| |
− | }
| |
− | 즉 private, protected 멤버는 그대로 있고, Parent 클래스의 public 멤버는 protected로 바뀌어 상속한다. protected는 외부에서 접근할 수 없고 파생 클래스 내에서는 접근이 가능하다는 특징이 있어 위의 코드는 에러가 난다.<ref name="C++상속">끝나지않는 프로그래밍 일기, 〈[https://blog.hexabrain.net/173 C++ 강좌 12편. 상속(Inheritance)]〉, 《개인블로그》, 2012-11-12</ref>
| |
− | | |
− | =====public 상속=====
| |
− | public 상속은 public 제한자보다 접근 범위가 넓은 멤버는 모두 public 제한자로 바뀌어 상속하게 되는데, public보다 접근 범위가 넓은 것은 없으므로 바뀌지 않고 그대로 상속하게 된다.
| |
− | class Parent {
| |
− | private:
| |
− | int num1;
| |
− | public:
| |
− | int num2;
| |
− | protected:
| |
− | int num3;
| |
− | };
| |
− |
| |
− | class Base : public Parent { };
| |
− | int main() {
| |
− |
| |
− | Base base;
| |
− |
| |
− | cout << base.num1 << endl; // error!
| |
− | cout << base.num2 << endl; // ok!
| |
− | cout << base.num3 << endl; // error!
| |
− |
| |
− | return 0;
| |
− | }
| |
− | | |
− | 위와 같이 코드를 작성했을 때, base의 num1과 num3는 에러가 나지만 기존에 public이었던 num2의 경우 에러가 생기지 않는다.
| |
− | | |
− | 상속의 접근 범위에 따라서 제한자를 잘 사용해주어야하는데 제한자의 접근 범위를 한 줄로 정리하면 아래와 같다.<ref name="C++상속">끝나지않는 프로그래밍 일기, 〈[https://blog.hexabrain.net/173 C++ 강좌 12편. 상속(Inheritance)]〉, 《개인블로그》, 2012-11-12</ref>
| |
− | | |
− | private < protected < public
| |
| | | |
| ===오버라이딩=== | | ===오버라이딩=== |
288번째 줄: |
156번째 줄: |
| | | |
| ==참고자료== | | ==참고자료== |
− | * 나무위키, 〈[https://namu.wiki/w/%EC%83%81%EC%86%8D(%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D)#s-2.3.1 상속(프로그래밍]〉, 《나무위키》
| |
| * 위키백과, 〈[https://ko.wikipedia.org/wiki/%EC%83%81%EC%86%8D_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D)#cite_note-1 상속(객체 지향 프로그래밍)]〉, 《위키피디아》 | | * 위키백과, 〈[https://ko.wikipedia.org/wiki/%EC%83%81%EC%86%8D_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D)#cite_note-1 상속(객체 지향 프로그래밍)]〉, 《위키피디아》 |
| * 재희 jaiyah, 〈[https://webclub.tistory.com/169 객체 지향 프로그래밍의 상속과 다형성]〉, 《Web Club》 | | * 재희 jaiyah, 〈[https://webclub.tistory.com/169 객체 지향 프로그래밍의 상속과 다형성]〉, 《Web Club》 |
296번째 줄: |
163번째 줄: |
| * 에스콸리, 〈[http://blog.daum.net/dsmcj/37 다중상속과 단일상속의 장단점]〉, 《개인블로그》, 2009-03-11 | | * 에스콸리, 〈[http://blog.daum.net/dsmcj/37 다중상속과 단일상속의 장단점]〉, 《개인블로그》, 2009-03-11 |
| * joker, 〈[https://blog.naver.com/heartflow89/220960019390 상속의 개념 및 부모/자식 클래스]〉, 《개인블로그》, 2017-03-17 | | * joker, 〈[https://blog.naver.com/heartflow89/220960019390 상속의 개념 및 부모/자식 클래스]〉, 《개인블로그》, 2017-03-17 |
− | * 신용권, 〈[https://www.hanbit.co.kr/store/books/look.php?p_code=B1460673937 이것이 자바다]〉, 《한빛출판네트워크》, 2015-01-06
| |
− | * 끝나지않는 프로그래밍 일기, 〈[https://blog.hexabrain.net/173 C++ 강좌 12편. 상속(Inheritance)]〉, 《개인블로그》, 2012-11-12
| |
− | * 녹두장군 - 상상을 현실로, 〈[https://mainia.tistory.com/2139 자바 다중상속 인터페이스 다루는 방법]〉, 《개인블로그》, 2015
| |
| | | |
| == 같이 보기 == | | == 같이 보기 == |
− | * [[상속]]
| |
− | * [[프로그래밍]]
| |
| * [[객체 지향 프로그래밍]] | | * [[객체 지향 프로그래밍]] |
| * [[클래스]] | | * [[클래스]] |
308번째 줄: |
170번째 줄: |
| * [[오버로딩]] | | * [[오버로딩]] |
| * [[메소드]] | | * [[메소드]] |
− | * [[필드]]
| |
− | * [[C++]]
| |
− | * [[생성자]]
| |
− | * [[인터페이스]]
| |
− | * [[재사용]]
| |
| | | |
| {{프로그래밍|검토 필요}} | | {{프로그래밍|검토 필요}} |