SSISO Community

시소당

◆ Constructor ◆

자,  이제  상속의  마지막  이야기를  하기  전에  한  가지  알아야  할  것이  있다.

  바로  constructor(생성자)라고  부르는  것이다.

다음의  예제를  보자.

  Manager  m  =  new  Manager();  

  뭐하는  코드인가?  바로  class  Manager를  근거로  해서  새로운  object를  만들고  있는  문장이다.

  그런데,  아마  궁금하게  생각하는  사람도  있었을  것이다.  new  다음에  왜  Manager()라고  썼을까?  Manager()란  method를  호출하는  문장과  유사하지  않는가?

  

  그렇다.  그렇게  생각했다면  예리한  생각을  한  것이다.  다음의  예제를  보자.

class  Manager  extends  Employee{

                                String  department;

                                Employee  subordinamtes  [];

                                long  bonus()  {

                                                      return  salary  *  3;

                          }

                  Manager()  {

                                  System.out.println("난  constructor.");

                        }

}  

  

  이  예제에서  자세히  볼  부분이  바로  line  7이다.  Manager()라는  method가  있다.

  그런데  생김새가  좀  이상하다.

  다  아시는  사실이겠지만  Java에서  사용되는  method는  반드시  return  type이  있어야  한다.

return  되는  값이  없으면  void라고  반드시  써야  한다.  그런데  이  method는  아예  그것도  없다.

    또  한가지,  어랏!  method  이름이  대문자로  시작하네?  원래  member들은  모두  소문자로  시작해야  하는데  말이다(물론  대문자로  시작한다고  해서  compile  error발생하는  것은  아니다.

convention일  뿐이다).  더군다나  자신의  class  이름과  정확히  동일하기까지  하다.

  그렇다.  지금  설명한  특징을  가지고  있는  것이  바로  constructor이다.  즉,  return  type이  없고  class  이름과  대소문자까지  정확히  같은  것.

    그럼  constructor가  무엇인가?  이것은  일반  method랑  분명히  다르다.  이것은  object가  생성될  때  단  한  번  자동으로  수행된다(또한  무조건  수행된다).

  

  따라서  위의  예제  class를  object로  만들면  어떻게  될까?  다음을  보자.

  Manager  m  =  new  Manager();  //  이순간  화면에  "난  constructor"  문장이  찍힌다.

  

  위의  new  다음에  나오는  Manager()가  정확히  constructor를  호출하는  것과  같지  않은가.

하여간  constructor가  수행되기  때문에  line  8의  코드가  수행되어  화면에  "난  constructor"라  찍히게  되는  것이다.

  그러면  이  같은  constructor를  사용하는  이유가  무엇인가?  일반적으로  constructor는  member  변수를  초기화  등에  주로  쓰인다(즉,  object의  초기화에  주로  쓰인다).

  그런데  또  궁금한  점이  있을  수  있다.  지금까지  나는  constructor를  만들어  사용한  적이  없는데도  위의  코드처럼  object를  만들지  않았던가?  constructor가  무조건  수행된다면,  만들지  않은  constructor를  호출하니  당연히  compile  error발생해야  하는  거  아닌가?

  그렇다.  constructor는  반드시  있어야  한다.  그렇다면  뻔한  이야기이다.  내가  만들지도  않았는데,  object가  생성되었다?  이  말은  누군가가  나  대신  constructor를  만들어  주었다는  결론이다.  그럼  누가  만들어  주었는가?

  

  바로  compiler가  constructor가  존재하지  않으면  대신  하나를  만들어  주는데,  내용은  하나도  없는  빈  constructor를  만들어  줄뿐이다(그러나  constructor가  존재한다는  것이  중요한  사실인  것이다).

  이렇게  compiler가  자동으로  생성해  준  constructor를  default  constructor라고  한다.  이  용어는  꼭  기억해야  한다.  default  constructor는  다음과  같이  생겼다.

  Manager()  {  //  argument도  없고,  하는  일도  없다.}

  

    좀더  구체적인  다음의  예제를  보자.

class  Manager  extends  Employee{

                            String  department;

                            Employee  subordinamtes  [];

                            long  bonus()  {

                            return  salary  *  3;

                                    }

                      Manager()  {

                                            name  =  "손오공";

                                            salary  =  500;

                                            department  =  "인사부";

                        }

                }  

  

  이  class를  object로  만들면,    member  변수  값이  초기화된다.

  이런  용도로  주로  constructor가  사용된다.  여기서  또  반드시  알아두어야  할  것이  있다.

이렇게  명시적으로  constructor를  만들면  compiler가  default  constructor는  만들어  주지  않는다.

  

  좀  더  달라진  예제를  보자.

class  Manager  extends  Employee{

Manager(String  name)  {

                this(name,  100);

}

Manager(String  name,  Long  salary)  {

                this.name  =  name;

                this.salary  =  salary;

}

}  

  

  위의  예제에  관해서  할  말이  많이  있다.  먼저  2  line,  5  line이  constructor들인데  이렇게  같은  이름의  method를  얼마든지  만들  수  있다.  이것을  보고  method  overloading이라고  부른다.

  method  overriding과  더불어  꼭  기억해야  한다(overriding은  부모로부터  상속받은  것을  재정의  하는  것을  의미한다).

  

  method  overloading을  할  때  주의할  사항이  있는  데  다음과  같다.

  같은  이름의  method들의  return  type은  같아도  되고  달라도  된다.  그러나  반드시  argument는  달라야  한다.  다음이  그  예이다.

  int  func(int  x)  {  ...  }

                

                int  func(int  x,  int  y)  {  ...  }

                

                char  func(char  x,  String  y)  {  ...  }

  

      위의  3가지  method를  호출할  때  어떤  method가  호출될  것인가?  만약  func(3)이라고  호출하면  첫  번  째  것이,  func(3,3)하면  두  번  째  것이,  func('a',  "안녕")하면  세  번  째  것이  호출된다.

  만약  func(3,'3')하면?  이건  error이다.  해당하는  method가  없기  때문이다.

  이렇게  method  overloading을  이용하면  강력한  program을  개발할  수  있다.

  자,  이제  constructor에  대한  이야기를  계속해보자.  위의  예에서  같은  이름의  constructor가  두  개  있다.

  즉,  method  overloading이  일어난  것이다(constructor가  일반  method와는  좀  다르지만  그래도  method의  일종임을  기억하자).

  

  그러면  이  Manager  class의  object를  만들려면  어떻게  해야  하는가?  다음과  같다.

  Manager  m  =  new  Manager("웹아이티");

  

  이렇게  하면  위의  예제의  2  line의  constructor가  수행될  것이다.  그런데  이  constructor의  내용을  보면  재미있다.  3  line의  코드에서  this()  method를  호출하는  데,  이는  다른  constructor를  호출하는  것이다.  this를  그냥  쓰면  자신의  object를  지칭하는데  사용되고,  this()는  자신의  object의  다른  constructor를  호출하는데  사용된다.

  3  line에서  this(name,  100);  라고  호출하면  method  overloading에  의해서  5  line의  constructor가  호출하게  된다.  이  때  name에는  "웹아이티"라는  String  object가  넘어간다.

  

그럼  다음과  같이  호출하면?

  Manager  m  =  new  Manager("웹아이티",  500);

  

  5  line의  constructor가  바로  호출된다.  그럼,  다음과  같이  호출하면?

  Manager  m  =  new  Manager();

  

  이미  말했지만  이  문장은  default  constructor를  호출하는  문장이다.

  그러나  예제에서는  default  constructor가  없다.

  아까도  말했지만,  constructor를  하나라도  만들면  compiler는  default  constructor를  안  만들어  준다는  사실을  잊지  말자.  따라서  위의  문장은  error가  발생하는  것이다.

  

  그러므로  여기서  주의할  사항이  있다.

의도적으로  constructor를  만들  때  반드시  default  constructor에  해당하는  constructor를  만들어  주는  것이  좋다.  (default  constructor는  argument가  없는  것을  말한다.)

  

  다음의  예제를  보자.

class  Manager  extends  Employee{

                          Manager()  {  //  default  constructor

                                              this("자바누리");

                                  }

                          Manager(String  name)  {

                                            this(name,  100);

                              }

                        Manager(String  name,  Long  salary)  {

                                            this.name  =  name;

                                            this.salary  =  salary

                      }

}

  

  

  위의  예제에서  2  line이  default  constructor에  해당된다.  3  line은  무엇을  의미하는지  알  것이다.

꼭  default  constructor에  body를  넣을  필요는  없다.  다음과  같이  해도  된다.

            Manager()  {  //  default  constructor}

  

  한  가지  기억할  점은  constructor는  상속되지  않는다는  것이다.  즉,  상속을  받을  때  부모의  모든  것을  가지고  오지만,  constructor는  상속되지  않음을  기억하자.

556 view

4.0 stars