2011년 5월 4일 수요일

자바의 상속(Inheritance)

자바의 객체지향 프로그래밍(OOP, Object Oriented Programming)에 대해서 논할때 어김없이 등장하는게 바로 이 상속(Inheritance)이란 개념이다. 자바의 상속을 공부하면서부터 많은 프로그래머들이 알던것도 가물가물해지고 모든게 뒤죽박죽되어서 절망(?)의 늪에 빠지는 이들이 상당수다. 특히 이런 상황이 초래되는 이유중에 하나가 발단부터 즉 의미부터가 다르기 때문이다. 상속이라는 말의 의미는 부모가 자식에게 뭔가를 물려주는 것이다. 그럼 물려주고 나면 자식은 가진게 더 많아지지만 부모는 가진게 없어진다. 이게 상속의 본질적 의미겠지만 자바에서는 자식(클래스)이 부모(클래스)한테 상속받았다고 해서 부모가 가진게 없어지는게 아니고 그냥 그대로다. 자식이 단지 가진게 많아질 뿐이다. 자식이 물려는 받으나 부모가 가진게 줄지는 않는다. 상속+공유의 개념으로 이해하는게 더 나을 것이다.

자바의 상속에 대해서 다시 확실하게 정립하겠다. 자바의 상속이란 자식 클래스가 부모 클래스에 있는 생성자를 제외(상속되지는 않지만 자식클래스의 레퍼런스를 만들때 부모클래스의 생성자가 자동으로 먼저 실행되고 자식클래스의 생성자가 실행된다.)한 모든 것을 물려받아 같이 공유하며 이를 더 확장(extends) 발전시키는 것이다. 부모클래스를 Superclass = Parent Class = Base Class라고 하고 자식클래스를 Subclass = Child Class = Derived Class라고도 한다. 또한 부모가 가지고 있는 멤버요소와 똑같은 것을 자식도 가지고 있을 경우(오버라이드 Override 혹은 오버라이딩 Overriding) 자식의 멤버요소를 부모가 가지고 있는 것보다 더 확장 발전시킨걸로 간주하고 자식 클래스에 있는 해당멤버를 사용한다. 그리고 부모와 자식 사이에 파이널(final)이란 넘(?)이 있는데 이 final은 부모자식간에 사이좋게 지내고 공유하는 것을 못하게 막는다. final이란 딱지가 클래스 앞에 붙으면 그 클래스는 물론이고 그 하위에 있는 메소드나 필드(선언된 변수들이 있는 공간)까지 몽땅 final이 되어 상속(공유)받지 못하게 된다.

더불어 여러분이 자바에서 쓰는 모든 클래스는 이것(?)의 자식 클래스다. ?는 바로 Object다. Object(객체)란 클래스가 이미 자바 API(Application Programming Interface,레퍼런스 및 개발자 문서,클래스 라이브러리)에 있는데 자바에서 쓰는 모든 클래스는 자동으로 이 Object 클래스를 상속받는다. toString( ), notify( ), wait( ), equals(??)등 나중에 기회되면 보게 되겠지만 이런 메소드들이 Object 클래스안에 들어있는데 이런 것들을 자동으로 상속받기 때문에 따로 만들지 않아도 이런 메소드들을 어디서나 어떤 클래스에서나 쓸수 있다. Object 클래스는 모든 클래스 중에 최상위 클래스이자 모든 클래스의 부모다. 좀 폼(?)나게 설명하자면 "모든 클래스들의 아버지" 자바에서 "제우스" 같은 존재가 바로 이 "Object 클래스"다. 이런 까닭에 우리는 자바를 Object 즉 객체를 빼놓고선 자바에 대한 언어를 논할수 없다고 하는 것이고 상속을 빼놓고선 객체지향 프로그래밍을 상상조차 할수 없는 것이다.


지금까지 이래저래 주절된 것이 왜 그렇게 많은 사람들이 객체지향이네 상속이 어쩌네 객체가 저쩌네하는 말들 여기저기서 많이 들어봤을터인데 대부분이 이런 연유에서다. 필자가 자바의 상속에 관해 초정밀 압축시켜 넋두리(?) 삼아 말해보았는데 지금까지 쌓여있던 여러분의 궁금증을 어느 정도 해소해 주었길 바라면서 이제 본격적으로 자바의 상속에 대해서 공부해 보겠다. 한마디로 상속은 종합선물세트(?)다. 여러분이 지금까지 배웠던 생성자, 메소드, 변수등이 이리저리 교차하며 어떻게 작동되고 실행되는지 정신없을 것이다. 그러나 두려워하지 말자. 강이가 함께 할것이니까 말이다.ㅎㅎ ^^

자 그렇다면 자바에서 상속이 왜 필요한 것일까? 이것을 알아야 제대로 써먹을수 있을것 아닌가? 여러분이 프로그램을 짤때 뭔가를 구현해야되는 파트가 있는데 만들어야될게 엄청 많다고 치자. 그런데 우연히 어떤 클래스를 보니까 필요한 대부분의 기능들이 그 클래스안에 들어있더란 말이다. 이런 경우 자바에서는 원없이 가져다가 쓰라고 상속이란 강력한 기능을 탑재해 놓은 것이다. 프로그램을 제작할때 엄청난 시간과 비용절감을 가능하게 만들어주는 기능이 상속이라는 점은 누구도 부인할수 없을 것이다.

본격적으로 어떻게 쓰는지 보기로 하자. 이해를 돕기 위해 이름이 부모인 Parent 클래스와 이름이 Child 인 자식 클래스가 있다고 하자. Child 클래스가 Parent 클래스의 상속을 받는 명령은 다음과 같다.

class Parent
{
,,,
,,,,,,
}

class Child extends Parent
{
,,,     //부모(Parent)에서 상속받은것(없어도 있다고 생각한다.)
,,,,,,  //부모에서 상속받은것
.
..
...
}

위와 같이 extends란 명령을 써서 부모로부터 상속을 받는다. 예제를 보면서 상속에 대해서 보다 자세히 공부해 보기로 하자.(예제에서는 Child 클래스가 Test40이다.)


나는 Parent 생성자
100
Parent는 자동차를 소유

예제 출력의 결과가 위와같이 나오는데 상속의 개념을 잘 모른다면 이해가 되지 않을 것이다. 그럼 차근차근 코드를 살펴보자. 처음에 Test40 클래스의 레퍼런스 t(Test40 클래스를 참조하고 있는 인스턴스)를 만들었다. 객체 생성을 하였으니 Test40안에 생성자가 있는지 살펴본다. 보다시피 Test40안에는 생성자가 없다. 아니 엄밀히 말하면 눈에 보이지는 않지만 빈껍데기의 텅빈 Test40( ) 생성자가 있다. 저번에 생성자에 대해서 공부하였으니 알고 있으리라 간주하겠다. ㅎㅎ 그래서 아무것도 없는 생성자를 실행하고 객체 t를 만든다.

다음을 보니까 t.money에 100을 넣으란다.(변수를 만들고 보니 교통카드랑 이름이 같구나.ㅎㅎ) 그런데 Test40의 어디에도 money라는 변수는 없다. 그런데 어떻게 값을 초기화시키라는건가? 자세히 보니 extends 라는 키워드가 클래스 옆에 보인다. 바로 그거다! 어떤 멤버와 필드를 상속받았던 것이다. 어디로부터? Parent 로부터 말이다. 그럼 Parent 클래스를 찾아본다. 여기서야 클래스가 두개 뿐이니까 헤멜 필요가 없다.^^ 아니나 다를까 money가 있다. 그래서 자식인 Test40클래스에서도 이 변수를 사용할수 있다. 그래서 100을 출력한다. 그리고 결과를 맞춰보니 100을 출력하긴 하는데 그 위에 또 뭔가를 출력했다.?

희한할 것이다. Test40 자신의 생성자도 아니고 난데없이 부모인 Parent 클래스의 생성자를 실행했다. 왜일까? 여기에 상속의 또다른 특징이 있는 것이다. 상속을 받았을 경우 객체 생성시 자식의 생성자를 실행하기 전에 부모의 생성자인 Parent( )를 먼저 호출해서 실행하고 그 다음에 해당 자식의 생성자를 실행하고 객체가 만들어지는거다. 그런 까닭에 예제에서도 객체생성시 "나는 Parent 생성자" 라인이 출력된 것이고 자식의 생성자는 있긴 하지만 보이지는 않는 빈껍데기니까 어떤 실행결과도 볼수 없는 것이다.(사실 상속시 부모 생성자가 호출되는 이유는 자식 생성자 내부에 super( )라는 부모 생성자를 호출하는 키워드가 자동으로 만들어져 숨어있기 때문인데 이 내용에 대해서는 다음에 따로 시간을 할애하여 설명할 것이니 그런게 있다고만 알아두자.)

메인메소드 마지막 줄에 있는 t.car( );도 money와 마찬가지로 원래 자식한테 있는게 아니었지만 부모한테 물려받았으므로 부모 클래스안에 있는 것처럼 자유롭게 이 메소드를 쓸수 있는 것이다. 따라서 car 메소드의 실행값을 출력하고 프로그램이 끝난다.

어떤가? 할만한가? ^^ 상속을 함으로 인해서 여러가지 가능해지는 프로그래밍 기법들(?)을 이제 하나씩 배워나가야 한다. 그 중에 하나가 방금전 얘기한 super 라는 키워드이고 이 밖에 알아야할 것들을 다음부터 만나보는 시간을 갖기로 하겠다. 자바에서 상속은 알짜배기 핵심기능 중의 하나이니 다시 한번 내용을 읽고 궁금증이 생기는 것들은 예제를 응용해 가면서 실험해 보기 바란다. 수고했다. ^^

댓글 8개:

  1. 정말 잘보았습니다 이런 유익한 블로그에 댓글이 없다니ㅜ

    답글삭제
  2. 잘보고있습니다. 감사합니다.

    답글삭제
  3. 잘 보고 있습니다. 감사해요^_^

    답글삭제
  4. I leave a response each time I like a article on a website or if I have something to contribute to
    the discussion. Usually it's caused by the fire communicated in the article I read. And on this post "자바의 상속(Inheritance)". I was excited enough to post a thought ;-) I do have 2 questions for you if it's
    allright. Could it be only me or does it seem like a few of the comments come across like coming from brain dead
    individuals? :-P And, if you are writing at additional sites, I'd like to keep up with you. Would you list all of all your communal pages like your linkedin profile, Facebook page or twitter feed?

    my blog post best cellulite treatment

    답글삭제
  5. 어떤 자바 책보다 이렇게 필요한 내용만 간추리고 알기쉽게 설명해주셔서 너무 감사합니다.

    답글삭제
  6. 시간이 많이 지났지만 잘 보고 있습니다. 정말 감사합니다.

    답글삭제