상세 컨텐츠

본문 제목

[JAVA] 찐 문과 출신이 쉽게 설명하는 인터페이스와 클래스의 차이

개발

by 베르월드 2023. 1. 4. 15:00

본문

※약간의 사설부터 시작합니다. 급하신 분들은 중간 Q&A부터 읽어주세요.

 

좀 더 효율적인 코드를 짜기 위해 디자인패턴을 공부해야 한다는 얘기를 듣고 대표님께서 추천해 주신 ‘헤드퍼스트 디자인패턴’ 책을 읽어보았다. 이 책은 예시를 구체적으로 들어주고 읽기 편한 형식으로 쓰여있다는 장점이 있다. 내가 읽은 첫 10페이지의 내용은 ‘오리’를 예시로 설명을 하고 있었다.

첫 시도 :

  1. Duck이라는 슈퍼클래스를 생성한다.
  2. Duck의 상속을 받는 자식 오리 클래스를 생성한다.
  3. 슈퍼클래스에 오리의 공통적인 특징 메서드를 생성한다.
  4. 각각 자식의 모양새가 다르므로 자식클래스에 각각의 특징인 display() 메서드를 생성한다.

문제점 발생 : 슈퍼클래스에 fly()라는 메서드를 생성했더니, 날면 안 되는 고무 오리가 날기 시작했다.

해결 : 고무오리 클래스에서 fly()에 아무것도 하지 않도록 오버라이드를 한다.

 

두 번째 문제 발생 : 6개월마다 업데이트를 하게 되면 그때마다 고무오리의 fly() 메서드를 상황에 따라 다시 오버라이드하기를 반복해야 한다.

 

두 번째 시도 :

  1. Flyable 인터페이스를 생성하여 fly() 메서드를 추가한다.
  2. 날 수 있는 오리들에게만 Flyable 인터페이스를 구현한다.

세 번째 문제 발생 : 추후 날아가는 동작을 바꾸려면 모든 날아다니는 오리 자식클래스를 고쳐야 함. 또한 모든 오리가 같은 방식으로 날아다니는 것이 아님.

 

세 번째 시도 :

  1. 새로운 요구 사항이 있을 때마다 바뀌는 부분을 분리한다.
  2. 바뀌는 부분을 따로 뽑아서 캡슐화한다.
  3. 바뀌지 않는 부분은 그대로 두고 바뀌는 부분만 고치거나 확장한다.

나는 이 부분까지 읽다가 책을 덮었다. 이쯤에서 나의 고질적인 문제가 나타났기 때문인데, 사실 나는 지금까지 ‘인터페이스’와 ‘클래스’, ‘상속’, ‘오버라이딩’, ‘오버로드’,’ 인스턴스’ 등의 개념을 정확하게 이해하지 못했기 때문이었다. 그래서 나는 책을 덮고 구글에 ‘인터페이스와 클래스’를 검색했다.

 

그만 알아보자..

티스토리의 개발자들은 왜 이렇게 어려운 말로 설명을 하는 것일까..

블로그 글 보는 것은 패스하고 야근중인 동료들 자리로 찾아가서 물었고 우리는 열띤 토론을 했다.

이 대화를 Q&A 형식으로 풀어보겠다.

 

————————————————————————————————

Q1. extends와 implements의 차이가 무엇인가?

A1. extends를 먼저 설명하자면

이렇게 부모를 extends한 자식이 있다고 생각해 보자. 자식은 걸음마만 할 수 있지만 부모를 상속받으면 노래하기 메서드를 그대로 가져와서 부모와 똑같이 노래할 수 있으며 여전히 걸음마도 할 수 있다.

 

implements는 아래 그림을 보면서 설명하겠다.

인형놀이는 화장도 하고 머리 빗기기도 하고 옷도 입히는 것을 말한다. 그러나 이 인형놀이는 하는 사람마다 상세 내용이 다르다. 예를 들어 누나는 인형놀이를 할 때 화장, 머리 빗기기, 옷 입히기를 하는 것은 똑같지만 어떤 식으로 화장하는지, 어떻게 머리를 빗기고 어떤 옷을 입히는지는 동생과 방식이 전혀 다르다.

 

정리해 보자면, extends는 부모의 메서드를 그대로 가져와서 자식이 가지고 있는 것보다 더 많은 것을 가질 수 있고, implements는 추상적인 행위만 가져오고 구체적인 행위는 자식이 정한다는 차이가 있다.

 

Q2. 그렇다면 인터페이스와 클래스의 차이는 무엇인가?

A2. 엄밀히 말하자면 인터페이스와 추상클래스를 비교해야 하는데 그 예시는 위의 예시를 이어서 설명할 수 있다. 위에서 노래를 하는 부모와 자식이 ‘클래스’라는 것이고, 인형놀이가 ‘인터페이스’라는 것이다.

클래스는 ‘상속(extends)’을 받는 것이고, 인터페이스는 ‘구현(implements)’ 하는 것이다.

 

공통점과 차이점을 정리하여 설명하자면,

공통점 : 메서드에 한해서 부모에게 있는 메서드를 모두 자식이 구현해야 한다는 것이다.

클래스든 인터페이스든 부모에게 ‘화장, 머리 빗기기, 옷 입히기’라는 메서드가 있으면 자식도 저 3가지를 빠짐없이 모두 받아와야 한다.

 

차이점 : 추상 클래스는 ‘상속(extends)’을 받고, 인터페이스는 ‘구현(implements)’ 하는데,

‘상속(extends)’은 다중으로 사용하지 못하고 (extends A, B) X

‘구현(implements)’은 다중으로 사용할 수 있다.(implements A, B) O

 

Q3. 오버라이드(Override)와 오버로드(Overload)의 차이는 무엇인가?

A3. 오버라이드(Override)는 자식입장에서 부모에게 implements받은 메서드를 구현하겠다고 선언하는 것이다.

이때, 그 메서드의 이름, 파라미터 자료형, 리턴 자료형이 모두 부모와 같아야 한다.

 

오버로드(Overload)는 같은 메서드이지만 파라미터 자료형은 다르게 선언할 수 있다.

부모에게는 없는 이름만 같은 새로운 메서드를 만들 수 있는 것이다.

이때 꿀팁을 알려주자면, 부모 메서드의 파라미터를 제네릭으로 선언하면 자식들이 자료형을 자유롭게 사용할 수 있다.

ex)

부모의 메서드 : 인형놀이 <T> 화장();

누나의 메서드 : 인형놀이 <String> 화장(){…};

동생의 메서드 : 인형놀이 <Integer> 화장(){…};

 

Q4. 마지막으로 인스턴스는 무엇인가?

A4. ‘B’라는 객체가 있다고 하자,

B b; 이렇게 끝내버리면 얘는 그냥 객체다.

그런데 B b = new B();라고 객체를 새로 선언해 버리면 그게 인스턴스다.

————————————————————————————————

똑똑한 동료들 덕분에 개발 공부를 시작한 지 1년 동안 이해하지 못했던 것들이 한 번에 이해가 되었다.

내일은 오늘 이해하게 된 지식 덕분에 책을 더 잘 이해하면서 읽을 수 있을 것 같다.

 

 

관련글 더보기