반응형

인터페이스.. 추상클래스..추상메소드.. 너무복잡합니다

검색을 해도 잘 정리된 블로그는 이해할수는 있지만 정확히 뭐가뭔지 잘모를때

예제를 살펴보면 정확하게 알수 있습니다

예제를 검색해도 이해하기 어려운 부분이 있을수 있습니다

이럴때!!! 이미 잘 정리된(?) 정리라기 보다는 정의에 가까운 java api를 보면됩니다

우리가 import 해서 쓰는 클래스들 중에서 잘살펴보면 interface와 abstract 클래스와 메소드를 잘 활용한 클래스가 있습니다!

 그전에 최소한 뭐가뭔지는 알아야 되니 간단하게 정의해봤습니다

정의를 읽고난후에 설명드리겠습니다.

인터페이스란 간단히 말해서 클래스끼리 어떤방식으로 데이터를 주고받을것이냐에 대한

동작을 기술한것입니다.

일반적으로 클래스는 설계와 구현을 함께 할수있지만 인터페이스는 순수하게 설계만 하는것입니다.

 그렇다면 인터페이스를 왜 쓰는것일까요? 클래스에다가 설계와 구현을 모두할수있는데

굳이 따로할필요가 있을까라고 생각될겁니다.

예를 들자면 시간을 출력해야하는 상황에서 여러사람들이 시간을 출력하는 로직을 만들때

A라는 사람은 순수하게 시간만출력하자...

B라는 사람은 그래도 정확하게 시와 분까지만 출력하자..

C라는 사람은 무슨소리!? 초까지출력해야지!!

D라는 사람은 나라마다 다른데 나라도 명시해줘야지

라고 각자마자 생각이 다를수있습니다.

이럴때 공통사용방법을 지정하면 어디에서든 동일하게 시간을 출력하는것을 이용할수있을것입니다

(인터페이스에서는 static final 를 통해 변수를 선언할수있습니다)

이렇게 모든 클래스에서 공통으로 사용할 방법을 정의한 특별한 클래스를 interface라고

하는데 이 interface를 사용하기위해서는 implements로 사용한다고 명시해주고

interface에 정의되어있는 모든 메소드를 구현해줘야합니다.

다음으로...

그렇다면 추상클래스란 무엇이냐?

추상메소드가 하나이상 있는 클래스를 말합니다. 그렇다면 추상메소드란  무엇이냐..

public abstract void print(); 이거와 같이 {}가 없는 메소드를 말합니다

여기서 abstract를 빼줘도 에러가안납니다 뒤에 세미콜론인 ;으로 구분해주기때문에

하지만 알아보기쉽게하기위해서 abstract를 붙여주엇네요

추상클래스는 extends를 이용해서 사용할수있습니다

이제 간단한 정의 설명은 마치고 실제로 그렇게 사용되는지 왜그렇게 사용되었는지 알아보겠습니다

jadclipse를 plugin을 통해 설치안한분은 제 블로그에있는 나와있는 jadclipse 플러그인 설치 한후에 하면 훨씬 유용합니다.

일단 아무이유없이 Calender 클래스를 이용하여 날짜를 갑자기 출력하고싶어졌습니다

public class TestInterface {

    public static void main(String[] args) {
        Calendar cal =new Calendar(); //     <---- 하면어떻게될까여? Cannot instantiate the type Calendar 와 같이 오류가 뜹니다
    

    }

}

그렇다면 왜 오류가날까..컨트롤을 누른상태에서 Calender이부분을 왼쪽버튼으로 클릭해줍니다

(jad 설치시에만 가능 jad는 역컴파일러로 .class파일을 .java파일로 바꿔줍니다

그때 .class파일에 정의되어있는 Calender클래스를 보게끔 해주는 역활을 합니다)

윗부분만 조금만 보면 알수있는 사실들이 있습니다

public abstract class Calendar     //사실 1 :사실 Calender클래스는 추상클래스였다....

    implements Serializable, Cloneable, Comparable  //interface 세개를 implements를 사용하여 쓰고있다...
{
    private static class CalendarAccessControlContext
    {

        private static final AccessControlContext INSTANCE;

        static
        {
            RuntimePermission runtimepermission = new RuntimePermission("accessClassInPackage.sun.util.calendar");
            PermissionCollection permissioncollection = runtimepermission.newPermissionCollection();
            permissioncollection.add(runtimepermission);
            INSTANCE = new AccessControlContext(new ProtectionDomain[] {
                new ProtectionDomain(null, permissioncollection)
            });
        }


        private CalendarAccessControlContext()
        {
        }
    }

이러니깐!!! new 를 통해 객체를 못만듭니다. 왜냐고물으신다면 추상클래스는 new를 통해 객체를 생성할수없습니다.

왜냐고물으신다면 그렇게 정외가 되어있습니다.

두번째로 그렇다면 어떻게 쓸수있을까요? 위에 답은 이미나와있습니다..

추상메소들 모조리 몽땅~ 다 구현해주는 겁니다...

그렇다면 그렇게 해봅시다!

어떤가요? Calendar를 new 를 통해 객체생성이됩니다..

다만 좀 구현해줄께 많을 뿐이죠

아니 그렇다면...

public class TestInterface {

    public static void main(String[] args) {
//        Calendar cal =Calendar.getInstance();
      
           
        Calendar cal = new Calendar() {
           
            @Override
            public void roll(int i, boolean flag) {
                // TODO Auto-generated method stub
               
            }
           
            @Override
            public int getMinimum(int i) {
                // TODO Auto-generated method stub
                return 0;
            }
           
            @Override
            public int getMaximum(int i) {
                // TODO Auto-generated method stub
                return 0;
            }
           
            @Override
            public int getLeastMaximum(int i) {
                // TODO Auto-generated method stub
                return 0;
            }
           
            @Override
            public int getGreatestMinimum(int i) {
                // TODO Auto-generated method stub
                return 0;
            }
           
            @Override
            protected void computeTime() {
                // TODO Auto-generated method stub
               
            }
           
            @Override
            protected void computeFields() {
                // TODO Auto-generated method stub
               
            }
           
            @Override
            public void add(int i, int j) {
                // TODO Auto-generated method stub
               
            }
        };

    }

}

이렇게 많이 구현해주는데 시간이 많이 걸리는데..

왜 굳이 추상클래스를 사용하느냐라고 궁금할수있습니다

그런데.. 이렇게 대부분의 블로그들에서 공통된 오류가 있습니다...

추상클래스를 사용하기위해서는 abstract로 구현된 메소드를 오버라이딩해서 써야된다고하는데 사실 다른방법이 있습니다

import java.util.Calendar;

public class TestInterface {

    public static void main(String[] args) {


        Calendar cal = Calendar.getInstance();

    }

}  
이것입니다 getInstance()메소드가 무엇이길래 그러느냐..

그렇다면 봅시다!

    public static Calendar getInstance()

    {
        Calendar calendar = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault());
        calendar.sharedZone = true;
        return calendar;
    }

먼진몰라도(여기서 캡슐화의 특징이 나옵니다. 안에있는 로직이 어떻게 돌아가는지몰라도 이메소드를 쓰면 어떤결과가 나오겠구나.. 하는 아~주 좋은 점이죠)

) calendar를 생성해줍니다.

static이라는 것은 new의 선언 없이 객체를 생성할수 있게끔 해줍니다.getInstance메소드를 통해서요!

그렇다면 여기서 잠깐 추상클래스와 추상메소드를 정리해보면

추상클래스는 extends 를 통해 쓸수있는데 쓰기위해서는 오버라이딩 해줘야한다. 그렇지만 static과 적절한 메소드를 통해 오버라이딩을 해주지 않아도 쓸수있다.

 추상메소드란 추상클래스안에있는 것인데 {}와 {}안에 내용이 없는 메소드이다.

 그렇다면 이제 마지막으로 인터페이스란 무엇이냐

public abstract class Calendar    
    implements Serializable, Cloneable, Comparable  //이부분의 인터페이스를 살펴보겠습니다
{
    private static class CalendarAccessControlContext
    {

        private static final AccessControlContext INSTANCE;

        static
        {
            RuntimePermission runtimepermission = new RuntimePermission("accessClassInPackage.sun.util.calendar");
            PermissionCollection permissioncollection = runtimepermission.newPermissionCollection();
            permissioncollection.add(runtimepermission);
            INSTANCE = new AccessControlContext(new ProtectionDomain[] {
                new ProtectionDomain(null, permissioncollection)
            });
        }


        private CalendarAccessControlContext()
        {
        }
    }

 

package java.io;


public interface Serializable
{
}

 

package java.lang;

// Referenced classes of package java.lang:
//            Object

public interface Cloneable
{
}


package java.lang;

// Referenced classes of package java.lang:
//            Object

public interface Comparable
{

    public abstract int compareTo(Object obj);
}

어떻습니까? 한번 보는것이 여러번 설명하는것보다 눈에 잘들어오죠...

인터페이스를 정의하는데 순수하게 뼈대만을 설계하고 있습니다. 가장 기본적인 뼈대죠..

이보다 완벽한 예제는 없는것 같습니다.(제가 만든 예제는 아니고.. 기업에서 만든것이죠...)

제가 설명해드리고 싶었던것은 나무를 보는 것보다 숲을 보는 것이 이해가 빠른것같네요...

저도 사실 interface가 뭔지 추상클래스가 뭔지 이 글을 쓰기전에는 10의 1정도만 알고있었습니다.

어찌됫든 디컴파일러의 위력을 다시한번 느낄수있는 글인였던것같습니다


출처 http://seodh007.tistory.com/23

반응형

'Java기초' 카테고리의 다른 글

replace replaceAll 차이  (0) 2014.08.01
java stack trace  (0) 2014.05.09
JVM 메모리  (0) 2014.04.30
정규식 특수문자  (0) 2013.07.15
인터페이스 추상클래스  (0) 2013.07.11

+ Recent posts