티스토리 뷰
■ 서론
안녕하세요 박스여우입니다. 객체지향을 배울때 가장 혼동이 오고 무엇을 하는 개념이 될 수 있는 것들이 바로 인터페이스와 추상클래스가 아닐까 합니다. 이런 이유때문인지 회사의 면접을 볼때 객체지향을 잘 이해하고 있는지 확인하기 위한 단골 질문으로 나오는 문제이기도 합니다. 이번 포스팅에서는 인터페이스와 추상클래스에 대해 알아보도록 하겠습니다.
■ 인터페이스 - Interface
인터페이스 무엇일까요? 우선 그 내용을 사전에서 찾아보도록 하겠습니다.
사물간 또는 사물과 인간 간의 의사소통이 가능하도록 일시적, 영속적인 접근을 목적으로 만들어진 매개체 라고 합니다. 위처럼 위키에서 서술된 내용이 사실 이번에 알아보고자 하는 인터페이스와 어느정도 일치하는 부분이 있습니다. 이에 대한 내용은 우선 인터페이스의 사용법에 대해 알아본 뒤에 다시 다루도록 하겠습니다.
1 2 3 4 5 6 | public interface SampleInterface { static final int SAMPLE_CALL = 123; public void sampleInterface(String param); public void sampleInterface2(String param, int data); } | cs |
위 코드는 인터페이스의 예제 입니다. 위의 코드 처럼 인터페이스는 클래스를 구현하는것과 비슷하지만 제한된 규칙이 있습니다. 인터페이스의 내부에는 static 상수만 선언할 수 있고, 메소드의 선언부만 작성할 수 있고 실제적인 내용은 구현할 수 없습니다.
1. 메소드는 구현할 수 없다.
2. 상수만 선언할 수 있다.
인터페이스에 변수를 선언하면 자동으로 public static final 예약어가 붙기 때문에 굳이 적어줄 필요는 없습니다. 하지만 인터페이스에 상수를 선언하는것은 anti-pattern이기 때문에 사용하지 않는것이 좋습니다(요기 참조). 하지만 프레임워크나 라이브러리를 사용할 때 가끔 인터페이스에 상수가 선언된 경우가 있을 수도 있으니 숙지는 하고 계시는것이 좋을것 같습니다.
■ 추상클래스 - abstract class
추상클래스는 이름 그대로 추상적인 클래스를 말합니다. 추상클래스 역시 인터페이스와 비슷한 용도로 사용됩니다. 하지만 용도에 대해 알아보기전에 어떻게 사용하는지에 대해서 짚고 넘어가도록 하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 | public abstract class SampleAbstractClass { public int test = 123; public abstract void sampleAbstractMethod(); public abstract void sampleAbstractMethod2(String test); public void sampleDefaultMethod(){ System.out.println("sampleMethod"); } } | cs |
추상클래스도 인터페이스와 비슷하게 abstract예약어를 사용하여 구현이 안된 메소드를 선언할 수 있습니다. 하지만 결정적으로 인터페이스와는 다르게 일반적인 메소드가 구현이 가능하며 일반적인 멤버변수 역시 선언할 수 있습니다. 하지만 추상클래스는 말 그대로 구현이 덜된 클래스이므로 객체를 생성할 수 없습니다.
■ 인터페이스와 추상클래스를 사용하는 이유
인터페이스는 때때로 C#의 delegate와 같은 역할을 하고, 때로는 다중 상속을 할 수 있는 편리한 도구, 때로는 다형성이 가능하도록 공통점을 제공해 줄 수도 있습니다. 위의 위키에서 볼 수 있엇던 매개체 역할은 다형성과 delegate등에서 찾아볼 수 있을것 같습니다. 그리고 가장 강력한 이유인 확장성을 위해서 사용됩니다.
◆ OCP - Open-Closed Principle
객체지향 프로그래밍의 원칙에는 개방 폐쇄 원칙(OCP, Open-Closed Principle)이라는 것이 있습니다. 소프트웨어 개체(클래스. 메소드 등)는 확장에 대해 열려 있어야 하고, 수정에 대해서는 닫혀 있어야 한다는 원칙 입니다. 위에서 말했듯이 인터페이스는 이러한 OCP 원칙을 지키기 위해서 사용됩니다.
기존에 Android나 GUI, Thread(Runnable)을 구현해본 분들은 한번쯤 사용해 보았을 개념입니다. 인터페이스를 매개변수 또는 Listener로 설정하고 인터페이스를 통해 핵심적으로 또는 해당 결과에 대한 작업을 확장할 수 있습니다.
◆ 다형성
인터페이스는 여러가지의 목적으로 사용할 수 있지만, 다형성과 캡슐화의 목적으로도 사용할 수 있습니다. 아래 예제 코드를 통해 알아보도록 하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ------ TestInterface ------ public interface TestInterface { public void test(); } ------ TestObject ------ public class TestObject implements TestInterface{ @Override public void test() { System.out.println("test"); } } ------ Main ------ public class main { public static void main(String args[]){ TestInterface sample = new TestObject(); sample.test(); useInterface(new TestObject()); } public static void useInterface(TestInterface arg){ arg.test(); } } | cs |
그리고 main 클래스에서 useInterface 메소드를 보시면 TestInterface를 매개변수로 받고 있습니다. 이에 TestObject를 건내주어도 TestObject TestInterface를 구현하였기 때문에 정상적으로 수행될 수 있습니다.
◆ 다중상속이 되는 인터페이스! 만약 두 인터페이스에 같은 메소드가 있다면?
두 개의 인터페이스가 같은 메소드를 가지고 있고 두 인터페이스를 모두 상속받아 구현할때는 어떤일이 발생할까요?
답은 간단합니다. 두 인터페이스 모두 구현이 되지 않아 구현이 필요한 메소드 입니다. 따라서 구현은 하나의 메소드로만 하고 두 인터페이스가 해당 메소드를 같이 사용하게 됩니다.
'프로그래밍 > java' 카테고리의 다른 글
XML을 JSON처럼 사용하기 (4702) | 2016.12.16 |
---|---|
Interface 상수가 Anti-pattern인 이유 (435) | 2016.11.25 |
Java - 직렬화(Serialization) (403) | 2016.11.23 |
JVM 과 메모리 구조 (0) | 2016.11.23 |
JavaFX FXML과 Controller을 이용한 UI 구현 (0) | 2016.10.24 |