SSISO Community

시소당

[Java] Inner class

1.  Inner  Class

        말  그대로  클래스안에  사용하는  클래스입니다.  


1-1  왜  Inner  Class를  사용하는가?
        자바  튜토리얼에  따르면,  "Inner  Class는  바깥에서는  부를  수  없
        다(예외는  항상있는  법).  고로  클래스를  패키지  처럼,  혹은  패키
        지안에서  좀  더  구조적으로  관리하기가  쉽다"라고  설명을  하더군
        요.  또  한  가지  더  설명을  해  놓았는데  별로  맘에  내키지  않는
        부분이더군요.  그  외로  이벤트를  처리할  때  괜찮은  것  같더군요.
        그리구  뭐  내부  클래스를  참조  할  때  같은  클래스내에  있고  무엇
        보다  객체와  가까이에  있어서  이해가  쉽고,  관리가  편하다는  데
        글쎄요,  이건  개인의  취향에  따라  달라지겠더군요.



1-2  어떻게  사용하는가?
        Inner  Class에는  Adapter  Class,  Local  Class,  Anonymous  Class
        가  있습니다.

        -  바로  위에서  말했죠,  클래스  밖에서는  참조가  안된다구요.  예외
        도  있다구  말씀드렸죠.  그  예외는  직접  해결하세요.  전  정력이  딸
        려서리....^^;

        -  static  메쏘드안에서  Inner  Class를  참조할  때는  Inner  Class를
        static으로  만들어  주든가  Top-Level-Class  의  객체를  생성해서  참
        조해야합니다.

  
거꾸로  설명을하는  느낌입니다만,  익명  클래스  부터  먼저  설명을  하겠
습니다.  여러분께서는  어댑터  클래스  부터  보고  나서  로컬  클래스,  익
명클래스를  보셔도  좋겠습니다.

1-2-1  Anonymous  Class  (익명클래스?)
          말  그대로  이름이  없는  클래스입니다.  그러니  생성자(Constructor)
          는  당연히  없겠죠.

        예제  1-2-1-1)

        public  class  SIC  {
                public  static  void  main  (String  []  args)  {
                        new  SIC().prove().display();    //  1
                }

                public  SIC_IF  prove()  {    //  2
                        return  new  SIC_IF  ()  {    //  3
                                public  void  display()  {    //  5
                                        System.out.println("Did  you  get  it?");
                                }
                        };
                }

                public  interface  SIC_IF  {    //  4

                        void  display();
              }
        }

      

        첫번째  예제가  조금  쉬운가요?    아니면  좀  어려운가요?
        앞으로  이정도  난이도(?)의    예제를  만들어  가겠습니다.
        그나  저나,  예제에  대한  설명을  해드려야겠네요.
        주석에  번호를  매겨놓았죠?  그  순서대로  설명할께요.

        주석1  :  뭐  여기서는  별로  이상한  게  없죠.  늘  보던  코드일  테니깐
                요.
                none  static  메쏘드인  prove()를  static    메쏘드인  main()에서
                호출할  수  없다는  것은  다  아실거구,  그래서  new  SIC()하고  객

                체를  생성해서  참조하죠.  그런데,  display()가  약간  신경쓰이

                죠.

        주석  2  :  prove()를  함수를  보세요.  SIC_IF  라는인터페이스  타입을

                리턴하죠?  이것은  주석4에  나오는  인터페이스를  사용한  것입니

                다.  그럼  주석  4를  한번  볼까요?  인터페이스를  SIC  클래스  안

                에서  선언했죠.  JDK1.1에서부터는  이게  가능합니다.

                이  경우의  인터페이스도  하나의  내부  클래스라고  봐야겠지요.

        주석  3  :  SIC_IF  인터페이스형  Anonymous  클래스의  객체를  리턴하고

              있습니다.  왜  Anonymous  형  클래스  객체를  리턴할  때는  인터페이

              스를  이용하는가  하면  익명  클래스는  클래스  이름이  없기때문에

              객체를  생성한  뒤  그  객체  참조  방법을  쉽게  하기  위해서입니다.

        주석  5  :  이  메쏘드는  인터페이스에서  정의된것으로  당연히  구현  해

              주어야합니다.

        그외  :  익명클래스는  로컬클래스를  정의해서  리턴하는  것과  똑

                같은  결과를  가집니다.  다만  좀  더  간단하게  표현한거죠.

                익명클래스는  알아보기(이해가기)  쉽게  간단하게  작성하라는  말

                이있구  또,  잘만  쓰이면  관리하기가  더  쉽다  등등...  잔소리가

                많은데요,  그것도  다  사용하는  사람나름이죠.  다만  프로그래밍

                방식에도  관례가  있고,  예의(?)가  있다는군요.

      

        우와,  이거  생각보다  설명하기가  쉽지않은데요.  ^^;

        게다가  영문  윈95에서  한글을  쓰려니  환장하겠네요.  한글을  썼다

        영어를  썼다  바꿔하기가  상당히  어렵네요.

      

        익명  클래스에  대해  간단한  예제를  하나  더  들고  넘어가겠습니다.

        아차,  깜박하고  그냥  넘어갈  뻔했네요,  익명클래스에는  ()과  ;를

        꼭  붙여  주셔야합니다.

      

        예제  1-2-1-2)



public  class  SIC  {

        public  static  void  main  (String  []  args)  {

                gimmeMsg("Bad  Codes").display();

        }

      

        public  static  t_interface  gimmeMsg  (final  String  m)  {  //  1

                return  new  t_interface  ()  {

                        public  void  display()  {

                                System.out.println("Message  :  "+m);

                        }

                };

        }

        private  static  interface  t_interface  {

                void  display();

        }

}





아주  간단한  예제이네요.  주석  1  을  한번보세요.    파라메타에  final이라

고  선언해주었습니다.  이와같이  지역변수나  파라미터가  Inner  Class에서

참조되는  경우에는  final로  선언해주어야합니다.  왜  final  로  선언해  줘

야하는  고  하니  내부클래스의  메쏘드에서  지역변수나  파라메타를  사용하

기  위해서는  컴파일러가  내부클래스에서  읽을  수  있도록  그  내부클래스에

그  지역변수의  값을  복사를  합니다.  이때  혹시  생길지  모르는  동기화  문

제  때문에  final을  사용한다는군요.





1-2-2  Adapter  Class

내부  클래스라  함은  이  어댑터  클래스를  두고하는  말  같습니다.

사용하기도  아주쉽구요,  아무래도  가장    많이  쓰일  내부클래스일  것  같

군요.

우선  간단한  예제  부터  보죠.

예제  1-2-2-1)



public  class  SIC  {

        public  static  void  main  (String  []  args)  {

                new  IC().display();

        }

}

class  IC  {

        void  display()  {

                System.out.println("IC");

        }

}



위에  흔히  볼  수  있는  두개의  클래스가  있습니다.  하나로  합쳐볼까요?

재미있을겁니다.



예제  1-2-2-2)



public  class  SIC  {

        public  static  void  main  (String  []  args)  {

                new  IC().display();

        }



        static  class  IC  {

                void  display()  {

                        System.out.println("IC");

                }

        }

}



무엇이  달라졌습니까?  IC  클래스가  SIC  Class  안으로  들어가고

static  으로  바뀌었죠.

이렇게도  해보세요.  내부  클래스에서  static을  없애고  메인  메쏘드  위

에서  내부  클래스의  객체  생성을  해보세요.



예제  1-2-2-3)



public  class  SIC  {

        IC  ic  =  new  IC();

        public  static  void  main  (String  []  args)  {

                new  SIC().ic.display();

        }



        class  IC  {

                void  display()  {

                        System.out.println("IC");

                }

        }

}



위의  예제에서  IC  내부클래스의  객체를  생성할  때  statci  키워드를  준다

면  static  메쏘드내에서  바로  참조할  수  있습니다.  단,  그  Inner  Class

에도  static  키워드를  써  줘야  컴파일이  되더군요.  그럼  뭔가  좀  이상한

느낌(?)이  들죠?  아래의  예제는  각각의  참조  경우를  보여줍니다.  맘에

드는  것을  골라잡아서(?)  사용하시면  되겠습니다.



예제  1-2-2-4)



public  class  IC_Lec  {



        S  s  =  new  S();

        static  S  ss  =  new  S();

        NS  ns  =  new  NS();

        //static  NS  nss  =  new  NS();    Error

        public  static  void  main  (String  []  args)  {

                new  S().display();

                //s.display();  Error

                new  IC_Lec().s.display();

                ss.display();

                //ns.display();  Error

                new  IC_Lec().ns.display();

              

        }



        static  class  S  {

                void  display()  {

                        System.out.println("I  am  a  static  Inner  Class.");

                }

        }

        class  NS  {

                void  display()  {

                        System.out.println("I  am  a  none  static  Inner  Class.");

                }

        }    

}



어댑터  클래를  이정도에서  끝내겠습니다.



1-2-3  Local  Class(로컬클래스)

로컬  클래스라  하는  것은  블럭(메쏘드)안에서  정의되고  사용되는  내부  클

래스입니다.  그래서  블럭  밖으로  밖으로  알리기(객체를  리턴하기)위해서

는  익명  클래스처럼  인터페이스를  사용합니다.



블럭내에서  내부클래스를  정의하고  리턴하는  함수를  만들어  보고  내부

클래스에  대해서  설명을  마치겠습니다.



예제  1-2-3-1)



public  class  SIC  {

      

        public  static  void  main  (String  []  args)  {

                SIC  sic  =  new  SIC();

                t_interface  alo  =  sic.gimmeALocalObjet("All  right  by  me");

                alo.display();

                System.out.println(alo.type);

        }

      

        t_interface  gimmeALocalObjet(final  String  s)  {    //  1

              

                class  ALocalClass  implements  t_interface  {    //  2

                        public  void  display()  {    //  3

                                System.out.println(s);

                        }

                }

              

                t_interface  alocalclass  =  new  ALocalClass();    //  5

                return  alocalclass;    //  4

        }

      

        interface  t_interface  {

                String  type="The  type  of  this  object  is  t_interface";

                void  display();

        }

      

}

원문  :  http://database.sarang.net/study/java/doc-1/inner.html

624 view

4.0 stars