• [JAVA] :: 인터페이스(Interface)

    2018. 2. 19. 19:54

    by. 위지원

    자바에서는 클래스 다중 상속을 금지합니다.


    왜인지 알아보겠습니다. 아래 그림과 같은 상황에서 다중상속을 허용하게 되면 CreditLineAccount가 상속받아서 오버라이드한 메서드를 사용할지

    Account메서드가 가지고 있는 메서드를 사용할지 알 수 없습니다. 그렇기때문에 다중상속을 비허용하는 것입니다.





    그러면 여러개의 클래스를 상속하고 싶을 때에는 어떻게 해야 할까요?


    예를 들어 아래와 같은 상황이 있습니다. 단행본과 부록CD는 공통점이 많습니다. 대출일,대출인,대출상태...

    이 둘을 묶어서 슈퍼 클래스를 만들고싶지만 부록CD 클래스는 이미 CD클래스를 상속받고 있기때문에 불가능 합니다.

    이럴때 사용할 수 있는게 인터페이스 입니다.



    인터페이스는 제약 조건이 존재합니다. 공통 기능만 표현이 가능하다는 것입니다.  그래서 아래와 같이 기능에 대한 인터페이스를 작성할 수 있습니다.

    인터페이스는 상속이라는 용어 대신 구현(implementation)이라는 용어를 사용합니다




    대신! 상수필드는 선언할 수 있습니다. 키워드는 final static 을 사용합니다.



    이렇게 그냥 선언을 해도 상수라 할당을 금한다고 에러가 뜹니다.


                    


    책에 나온 예제를 따라 해봅시다. 아래와 같이 Lendable이라는 인터페이스에 상수 변수를 두개 추가합니다.



    그리고서 이 인터페이스를 구현한 클래스에서 사용할 수 있습니다.




    위에서 인터페이스는 "구현"한다~ 라고 하라하는데 상속도 물론 가능합니다. 물론 인터페이스끼리입니다. class에서 인터페이스를 상속하려고 하면 아래와 같은 에러가 발생합니다.



    여기서 주의할점은 구현할 때 구현할 인터페이스가 상속한 인터페이스까지 모두 구현해주어야 한다는 것입니다.



    이렇게 하면 다중상속도 가능해집니다.





    인터페이스 이름은 자바의 식별자 명명관례에 따르면

    1) 대문자로 시작하는 명사나 형용사로 정하는 것이 좋고

    2) 메서드 이름은 소문자로 시작하는 동사로 정하는 것이 좋다

    그러므로 위 예제에서는 인터페이스 이름을 Lendable 대출한다를 checkOut 반납한다를 checkIn 으로 지정합니다. 아래 그림과 같이 말이죠

    키워드는 interface라고 하면 됩니다.



    위에 그림을 보면 abstract를 적어준 메서드와 그렇지 않은 메서드가 있습니다. 컴파일러가 자동으로 abstract를 추가해주기때문에 괜히 안적어도 괜찮습니다.


    그럼 이제 인터페이스를 구현해줍니다. 구현은 implements 키워드를 이용합니다.


    위의 구현에서 보면 인터페이스에 있는 메서드를 구현할때 꼭 public을 붙이는것을 볼 수 있습니다. public을 지우면 아래와 같은 에러가 발생합니다.

    https://stackoverflow.com/questions/24773080/java-attempting-to-assign-weaker-class-privileges?lq=1

    을 참조해 알아보니 인터페이스의 메서드들은 public 키워드가 없더라도 모두 public 이기때문에(컴파일러가 자동으로 붙여줌) 인터페이스를 구현하는 클래스또한 public으로 해주어야한다고합니다.




    이제 다음으로는 부록Cd 클래스를 구현해봅시다.  먼저 CdInfo 라는 Cd 클래스를 선언을 해줍시다.그리고나서 이 cd클래스를 상속받고 거기다가 위와 같은 방법으로 Lendable이라는 인터페이스를 구현하는 방식을 사용할 것입니다.





    이제 이걸 사용해 볼  main함수를 작성해 보면 결과가 아래와 같이 출력됩니다.



    인터페이스로 할 수 없는것은 객체를 선언할 수 없다는 것입니다. 그렇기때문에 생성자도 필요없습니다.



    https://www.slipp.net/questions/52 이곳에서 인터페이스는 객체인가? 라는 재밋는 주제가 토론되었다.

    해당 사이트에서 taiseung.lee.3 이라는 분의 말에 따르면 아래와 같다.


     " 객체(instance - 구분하기 위해 실체로 말할 수 있다)라는 것은 자신만의 유니크한 identity와 상태 정보를 가지고 있어야 한다는 전제에 따라 인터페이스로는 객체를 생성할 수 없다는 결론에 도달하게 된다. "


    또한 자바지기님의 말에 의하면 아래와 같은 의견도 있었다.


    " interface는 명세지 객체가 아니다. "

    " 객체는 상태와 행위를 가져야 하는데 Interface는 행위만을 정의하고 있다. 상태는 없기 때문에 객체가 아니다. "




    대신해서 추상화할때와 마찬가지로 이 메서드는 꼭 선언해줘야해~ 라고 말하는것처럼 어떤 규칙을 제한할 수 는 있습니다.

    인터페이스에도 다형성이 있습니다. 추상화 할때와 동일합니다.




    추상화 다형성할때와 마찬가지로 인터페이스의 다형성을 이용하여 아래와 같이 프로그램을 작성할 수 있습니다.





    지금까지 코딩들 보면 익셉션을 throw 하고 있습니다. ( 이게 굉장히 안좋은 것이라고 수업시간에 배웠는데..크흡 )

    하지만 추상 메서드를 구현하는 메서드에서는 throws를 써도 익셉션을 던질 수 없습니다.


    SeparateVolume class에서 한번 던져보겠습니다. 아래와 같은 에러가 발생합니다. 이 에러를 해결하기 위해서는 인터페이스에서도 에러를 던져야합니다.



    아래와 같이 에러를 던져줫더니 SeparateVolume 클래스에서 에러가 사라진것을 확인할 수 있습니다.





    '2018년 > C, Java, FileSystem' 카테고리의 다른 글

    [Java] :: Object Class  (0) 2018.02.26
    [JAVA] :: 상속(inheritance)  (0) 2018.02.19
    [C] ::c언어 버퍼비우기 ,숫자만 입력받기  (2) 2018.02.09
    [File System] ::사분트리(QuadTree)  (0) 2018.02.02
    [File System] ::Grid File  (0) 2018.01.30