Search

반응형

'Abstract'에 해당되는 글 2건

  1. 2021.08.15 [Java]추상클래스(Abstract Class) 와 인터페이스(Interface) 쉽게 이해하기.
  2. 2020.05.05 [자바]추상클래스 vs. 인터페이스 사용방법. Abstract Class vs. Interface
반응형

안녕하세요. 신기한 연구소입니다.

최근에 프로젝트를 마치고 잠시 휴가를 즐기고 있습니다.

자바스크립트(javascript)를 공부하던 중 갑자기 자바의 인터페이스와 추상클래스가 떠오르더군요.

생각난 김에 정리를 해야겠어서 이렇게 포스팅해봅니다.

다양한 책을 읽어보면 추상클래스와 인터페이스에 대한 설명이 되어 있습니다.

두 개념을 비교하면서 설명을 하고 있는데요.

좀 더 이해하기 쉽게 설명해보겠습니다.

이번 포스팅은 코딩 없이 설명만 하겠습니다.

 

게임 캐릭터를 만든다고 생각해봅시다.

어떤 종족을 구현한다고 가정해보고 시작해봅니다.

그 종족은 모두 이마에 같은 종족 이니셜이 있다고 설계했습니다.

같은 종족들은 다양한 캐릭터가 있겠지만

공통된 부분은 바로 이마의 이니셜입니다.

종족은 몇 가지의 종류로 구성되며 추후 더 추가될 가능성도 있습니다.

각 캐릭터별 객체를 만들기 위해 클래스를 설계하는데요.

무조건 이마에 같은 이니셜이 있음을 빼먹으면 안 됩니다.

공통이라고 볼 수 있겠네요.

그래서 그 공통된 부분을 추상화해서 추상 클래스의 메서드로 구현해 둡니다.

방금 설명한 대로 추상 클래스는 각 캐릭터의 클래스의 공통된 부분을 추출해서

구현한 클래스이기에 이에 해당하는 객체는 없는 게 맞겠지요?

그래서 추상 클래스는 객체를 만들 수 없다기 보단 만들 필요가 없게 됩니다.

보통 책들을 보면 추상 클래스는 객체를 만들 수 없다,

구현되지 않은 추상 메서드로 인해 객체를 만들 수 없다고 하는데요.

신기한 연구소에서는 객체를 만들 필요가 없는 공통을 정의한 클래스라고 하겠습니다.

 

그런데 같은 종족을 대표하는 추상 클래스를 구성하고 이 클래스를 상속받아서

각 캐릭터 클래스를 설계할 건데요.

완벽하게 일치하는 기능인 경우는 상속받아서 활용하면 되지만

같은 행위지만 다른 방식이라면 모두 다른 메서드를 구성해야 합니다.

그럼 안 되겠지요?

이런 경우는 같은 행위에 대해 정의만 하고 상속받은 캐릭터 클래스에서

각자의 특성에 맞는 방식을 구현하게 하면 됩니다.

바로 추상 메서드라고 합니다.

추상클래스에서 메서드에 abstract를 붙이고 구현하지 않으면

상속받은 캐릭터별 클래스에서 해당 메서드를 

오버라이드(override)해서 각 캐릭터에 맞게 구현하면 된답니다.

예를 들어 공격, 이동, 방어 등이 있겠네요.

캐릭터별로 공격이라는 행위는 있지만

공격하는 방법(방식)은 다를 수 있기 때문이지요.

 

추상클래스(abstract class)에 대해 정리해 보겠습니다.

클래스를 설계하는 과정 중에 각 클래스들의 공통부분을 추출해서

상위 클래스로 구성하고 같은 기능, 방식이면 구현해서 사용할 수 있게 하고

같은 행위지만 방법(방식)이 다르면 추상 메서드로 정의만 해서

반드시 빼먹지 말고 구현할 수 있게 만든 클래스라 보면 되겠네요.

 

그럼 인터페이스는 무엇일까요?

어쨌든 이름도 확연하게 다르네요. ㅎㅎ

 

추상클래스는 클래스입니다.

그래서 클래스를 설계하는 과정에서 추상화하는 과정에서 생성된다고 보면 되는데...

인터페이스도 abstract라는 키워드를 사용해서 상수 또는 메서드를 정의만 합니다. 

인터페이스는 용어의 의미대로 겉으로 드러낸 기능이라고 보면 되겠네요.

클래스가 설계된 후 정리가 되었다면

게임을 시작하면 캐릭터들이 생성되는데요.

캐릭터 클래스를 가지고 각 캐릭터들을 객체로 인스턴스화 하면 된답니다.

이제 이 인스턴스들을 사용자들이 조작을 해야 합니다.

어떤 기능이 있는지 알아야겠지요?

그래서 클래스로 만들어진 객체(인스턴스)들이 어떤 기능을 활용할 수 있는지

그 부분을 정의한 것이 인터페이스라고 보면 됩니다.

 

각 캐릭터별로 보면

전진, 후진, 공격, 방어 등 다양한 기능들이 있는데요

이런 기능들을 빠트리지 않고 구현할 수 있도록

캐릭터들의 기능들을 구현하도록 정의한 것이 인터페이스입니다.

무조건 구현을 해야 하기에 설계를 잘해야겠지요?

또한 종족별로 초기 에너지, 공격 지수 등을 할당받아야 할 수 있습니다.

그런 부분 또한 인터페이스에서 abstract 상수로 정의해서 사용하면 

캐릭터를 생성할 때 누락되는 상황이 없겠지요?

 

모든 종족은 생명유지, 에너지 보충이라는 기능이 있다고 치면

그 부분에 대해 인터페이스를 구성하고

각 종족별 인터페이스와 모든 종족의 인터페이스를

동시에 구현하던지 상속 후 구현하는 방식으로 활용할 수 있겠습니다.

 

추상 클래스와 인터페이스는 사용법이 전혀 다릅니다.

클래스를 설계하면서 공통부분을 정리하기 위해 추상 클래스를 사용하는 것이며,

설계된 클래스를 이용해서 객체를 생성한 뒤

해당 객체를 사용할 수 있는 기능들을 정리한 것이 인터페이스라고 생각하면 됩니다.

 

사용자가 사용할 필요 없는 클래스끼리 구성되기 위해 사용하는 메서드가 있다고 칩시다.

객체의 타입과 생성자를 해당 클래스로 지정해서 생성할 경우,

사용자가 굳이 사용할 필요 없는 메서드까지 노출되고

사용자는 혼란스러워 할 수 있는 상황이 발생할 수 있습니다.

이런 경우는 사용자만을 위한 메서드를 정의한 인터페이스를

객체의 타입으로 지정하고 해당 객체의 생성자로 인스턴스화 한다면

사용자는 불필요한 메서드를 볼 수도 없고 혼란에 빠질 일도 없을 겁니다.

이제 인터페이스와 추상 클래스에 대해 어느 정도 정리가 되었을 거라 생각됩니다.

 

Map<String, Object> hm = new HashMap<String, Object>();

 

HashMap 클래스로 객체를 생성할 때 Map이라는 인터페이스의 타입으로 생성하고

Map에 정의된 인터페이스의 메서드만 활용한다는 의미입니다.

반응형
반응형

안녕하세요. 프로그래머 티보이입니다.

이번에 할 이야기는 바로 추상클래스와 인터페이스입니다. (Abstract Class, Interface)

자바를 배우고 사용하시는 분들에게는 아주 중요한 개념이므로 같이 정리해보겠습니다.

 

 

먼저 개념 정리부터 하겠습니다. (오늘은 코딩 없이 가 봅시다!!)

 

#추상클래스 (Abstract Class)

abstract [class_name] {
           abstract [return_type][method_name]();
}

 

추상클래스는 제어자 abstract를 사용해야 한다.

객체지향의 다형성을 위해 만드는 추상클래스는 다양한 클래스들의 공통된 부분을 묶어서 상속받을 수 있게 한다.

추상클래스는 제어자인 abstract로 구현한 추상메소드를 반드시 하나는 가지고 있어야 한다.

추상클래스에서만 추상메소드를 사용할 수 있고 추상메소드 선언 끝에 세미콜론(;)을 반드시 붙인다.

추상클래스는 자체로 객체를 생성(인스턴스화)할 수 없다.

extends(확장) 키워드를 사용해서 추상클래스를 상속 받을 수 있다. (상속은 단 1개만 가능)

추상클래스를 상속받으면 추상메소드는 반드시 재구현(override, 오버라이딩)해야 한다.

추상클래스는 다른 일반 클래스처럼 메소드와 변수를 선언 및 구현할 수 있고 자식클래스가 그대로 상속받아 사용할 수 있다.

 

#인터페이스 (Interface)

interface [interface_name] {

          Public static final [constant_name] = value;

           Abstract [return_type][method_name]();

}

 

인터페이스는 interface 키워드로 선언한다.

클래스는 implements(구현) 키워드로 여러 개의 인터페이스를 구현할 수 있고 물론 extends로 클래스를 상속 받는 것도 동시에 가능하다.

인터페이스를 implements하면 선언된 메소드를 모두 구현해줘야 한다.

메소드는 선언만 가능하고 구현할 수 없다. (추상메소드지만 abstract는 생략가능)

상수를 선언할 수 있다. (static final)

변수도 선언할 수 있다.

인터페이스끼리 extends를 사용해 상속이 가능한데 하나만 가능한 클래스와 달리 여러 개 가능하다.

 

여기까지는 보통 자바책을 보면 나와있는 내용입니다.

 

추상클래스와 인터페이스는 비슷한 듯 다른점이 있는데요.

추상클래스는 1개만 상속 가능, 인터페이스는 여러 개 구현 가능하고 인터페이스끼리는 여러 개 상속 가능.

추상클래스는 구현한 메소드가 존재하지만 인터페이스는 선언메소드만 가능.

 

이렇게 구분하는 것도 각각의 특징을 보면 알 수 있답니다.

 

그런데 가장 중요한 것은,

항상 교재를 이용해서 이론을 공부하다 보면 대부분 정의를 먼저 내립니다.

그리고 작성법을 알려주며 간단하게 비교도 해줍니다.

그렇게 이해하고 정리가 되긴 했는데

어떤 경우에 어떻게 사용하는지 설명하는 책은 아직 못찾았습니다.

혹시 여러분들도 그런 갈증을 해소하기 위해 책이 아닌 웹사이트를 검색하다 오신거 맞으시죠?

그런 부분을 설명해주는 것이 블로그의 묘미 아닐까 싶네요.

 

실전에서 어떻게 하는지는 설계자나 프로그래머의 몫입니다.

제 기준으로 간단히 설명해 볼께요.

 

반지의 제왕과 비슷한 게임 프로그램을 만든다고 가정하겠습니다.

유닛들을 만들어야 합니다.

유닛들은 객체로 구성할 수 있겠네요.

그렇다면 객체를 구성할 클래스를 설계해야 합니다.

모든 객체는 생명체입니다.

모든 생명체는 눈도 있고 심장도 뛰고(아직 살아있는지 죽었는지 판단시) 팔, 다리, 날개 및 꼬리 등이 있고 개수는 다를 수 있겠지요.

모든 생명체는 걷기, 뛰기, 공격, 방어, 날기 및 공격 포인트, 방어 포인트도 있을 것이고 무기관련 장착, 사용, 업그레이드 같은 기능이 있을 겁니다.

인간 객체, 오크 객체, 동물 객체, 요정 객체 등 다양한 객체들도 있을 거구요.

이렇게 간단하게 구상을 하고 설계를 한다고 했을 경우입니다.

모두 생명체이기에 추상클래스를 하나 만듭니다.

생명체는 기본적으로 눈, 심장, , 다리, 날개 등 기본값(변수) 및 설정하는 메소드(set)를 추상메소드로 선언해서 상속 받는 각 객체 클래스들에서 구현하게 합니다. 그리고 각 객체들의 현재 상태를 확인할 수 있는 메소드를 구현합니다.

이렇게 추상클래스는 객체들을 생성할 클래스의 공통점을 추출해서 기본 설정을 한군데 모아서 상속받아 사용할 수 있게 구성했습니다.

 

이제 인간, 오크, 동물, 요청 클래스는 생명체 추상 클래스를 상속 받아서 기본 값을 설정하는 메소드를 구현하고 현재 상태를 확인하는 메소드를 재정의 할 수도 있게 되었습니다.

 

다음으로 생각할 부분은 각 객체들은 걷기, 날기, 뛰기, 수영하기 등의 액션을 할 수 있고,

공격, 방어 등의 기능도 만들어야 합니다.

필수적인 이 기능들은 모든 객체들이 구현해야 하기 때문에 인터페이스로 구성합니다.

공격 명령을 내렸을 때 객체가 공격하기를 원한다면 그 공격 명령을 받고 실행할 부분이 필요하겠지요? 그런 부분들을 인터페이스로 구성하면 되겠네요.

그렇다면 인터페이스도 좀 더 분류해서 만들면 좋습니다.

우선 개념만 이해는 부분이니 두개의 인터페이스만 구성해봅니다.

기본적인 활동을 하는 걷기, 뛰기, 날기, 수영하기 등의 메소드를 선언한 인터페이스 하나와

능력을 표현하는 공격, 방어, 업그레이드, 수송 등의 메소드를 선언한 인터페이스로 구성합니다.

 

이제 인간, 오크, 동물, 요정등을 생성할 수 있는 클래스를 만들 것이고,

이 객체들이 생명체이기에 기본적으로 구성할 부분을 추출해서 공통(추상)화 한 추상클래스를 만들어 상속받게 하며,

각 객체들의 움직임과 능력에 대한 표현을 선언한 각각 인터페이스를 구현하면 됩니다.

 

이렇게 추상클래스와 인터페이스 사용에 대해 혼란스러워 하지 말고,

각 특징을 잘 이해하고 위 예시처럼 재량껏 사용하면 될 듯합니다. 

실전에서는 더 자세하고 많은 클래스와 인터페이스가 존재하겠지요?

추상클래스와 인터페이스를 어떻게 사용할 것인지 또한 설계자와 프로그래머의 노하우가 필요하지 않을까 싶네요.

즐코딩하세요~

반응형