언어(Programming Language)/Java

[Java] 추상(abstraction) 클래스와 인터페이스(Interface)

RyanSin 2021. 1. 28. 00:30
반응형

- 지난 시간

안녕하세요. 지난 시간에는 자바 오버 로딩(Oberloading)과 오버 라이딩(Overriding)에 대해 알아봤습니다.

 

혹시 놓치신 분들은 아래 링크를 통해 상속에 대한 개념을 학습하고 오시는 걸 추천드리겠습니다.

any-ting.tistory.com/32

 

[Java] 오버로딩(Overloading)과 오버라이딩(Overriding) 개념 및 사용법

- 지난 시간 안녕하세요. 지난 시간에는 클래스 상속에 대해 알아봤습니다. 혹시 놓치신 분들은 아래 링크를 통해 상속에 대한 개념을 학습하고 오시는 걸 추천드리겠습니다. any-ting.tistory.com/31 [

any-ting.tistory.com

- 개요

이번 시간에는 자바에 또 하나에 어려운 개념... 추상 클래스와 인터페이스에 대해 알아보겠습니다.

 

추상 클래스

추상(abstraction) 클래스란 무엇일까요? 사전에 정의를 보면 아래와 같습니다.

"공통되는 특성이나 속성 따위를 추출하여 파악하는 작용"이라고 설명하고 있네요.

 

그럼 프로그램에서 추상 클래스란 이와 같이 정의할 수 있습니다.

 

추상 클래스는 여러 클래스(개념)에서 공통되는 속성과 메서드를 파악해서, 하나의 추상 클래스를 통해 다른 여러 클래스들이 공통적인 속성과 메서드를 재 사용할 때 사용됩니다. 

 

위 설명 글만 읽었을 때는 우리는 머릿속에 그려지지 않아서 이해하기 어려울 거예요.

 

만약 동물을 예시로 든다면 동물들은 같은 공통점이 있습니다.(기본 클래스랑 다른 게 머지?... 의문이 들죠? 약간 차이가 있습니다.)

 

기본적인 클래스는 new 키워드로 객체를 만들 수 있지만, 추상 클래스는 만들 수 없습니다.

그리고, 속성이나 메서드를 정의해서 사용할 수 없습니다. (상속받은 클래스가 정의해서 사용!!) 

 

- 사용법

동물 클래스를 추상 클래스로 만들어보겠습니다.

 

추상 클래스는 class 앞에 abstract 키워드를 붙여서 만들 수 있습니다.

package Access;

//동물 추상 클래스
public abstract class Animal {

    public String name; // 동물 이름
    public int age; // 동물 나이
    public String type; // 동물 종류

    //잠자기
    public abstract void Sleep();

    //식사하기
    public abstract void Eat();

}

기본적으로 동물에는 이름과 나이 그리고 종류가 있죠 그리고 당연한 거지만 ㅎ 잠자고 밥을 먹습니다.

 

그리고 메서드에는 abstract 키워드를 붙여 만들어야 해당 메서드를 추상 메서드로 만들 수 있습니다.

(속성은 안 해도 됩니다. 자세한 내용은 아래 인터페이스 단락에서 확인하시면 됩니다.)

 

이제는 기본적인 속성과 기능을 정의한 추상 클래스를 사용해보겠습니다.

 

강아지 클래스를 만들고 동물 클래스를 상속받겠습니다.

 

상속받고 나면 빨간 줄이 표시됩니다. 이유는 추상 메서드를 Override 해서 기능을 사용하라는 이유입니다.(자세한 부분은 아래 인터페이스 단락에서 확인해보세요.)

 

아래와 같이 선언해서 사용하면 됩니다.

package Access;

public class Dog extends Animal{
    
    @Override
    public void Sleep() {
        
    }

    @Override
    public void Eat() {

    }
}

 

빈 메서드가 생성이 되었고, 메서드 안에 해당 강아지 클래스에 맞게 로직을 만들면 되겠죠?

 

다른 클래스도 마찬가지입니다.

 

고양이, 새, 물고기 등등... 여러 가지 동물들에 기본적인 속성과 기능은 동물 클래스에 정의하고 모두가 사용하면 됩니다. :)

 

- 추상 클래스를 사용하는 이유

추상 클래스는 사실 꼭 사용할 필요는 없습니다. (프로젝트 단위가 적을 때는 말이죠.)

 

기술이란 결국 상황에 맞게 우리는 잘 설계해서 사용하면 됩니다. 좋은 기술, 나쁜 기술은 없다고 생각해요.

 

그럼 추상 클래스를 언제 사용하면 좋을까요?

 

위 예시처럼 구조가 꼭 사용해야 할 때, 아니면 협업을 하는 데 있어서 기본적인 틀을 만들어 놓고 시작할 때 좋아요.

 

무슨 말이냐면, A와 B라는 기능을 만드는데 사실 이 기능들을 그냥 만들다 보면(설계를 안 하고... 문제예요 ㅋㅋ...)

 

필요한 거 불 필요한 거 공통적인 거 공통적이지 않은 것 등등... 다양한 상황이 발생해요. 그리고 내가 아닌 다른 개발자가 생각은 제가 알 수 없죠?

 

그렇기 때문에 서로 하나에 틀을 만들어 놓고 나는 A를 만들고 다른 개발자는 B를 만드는 거죠 수정 사항이 있으면 추상 클래스만 가지고 상의하면 되기 때문에 어떻게 보면 이런 상황에서도 사용될 수 있다고 볼 수 있어요.

 

여러분들 상황에 맞게 꼭 사용하는 걸 추천드려요! 답은 없습니다. :)

 

인터페이스

인터페이스(Interface)! 인터페이스란 무엇일까요? 사전에 정의를 보면 아래와 같이 설명하고 있습니다.

인터페이스(Interface)

 

사용자 인터페이스, 접속기(컴퓨터와 프린터 사이의 접속기), 접점(두 가지 주제 시스템 등이 서로 만나서 영향을 주고받는 영역)

 

위 내용을 잘 읽으면 아래와 같은 상황을 만들 수 있습니다.

 

 

드라이기를 사용하려면 드라이기 코드 선을 콘센트에 꽂아야 합니다.

 

여기서 인터페이스는 드라이기 코드와 콘센트가 만나는 부분입니다.

 

그리고 연결된 부분을 통해 에너지를 드라이기로 전달합니다.

 

 

우리가 상대방과 통화를 할 때, 사실 기지국을 통해 나와 상대방에 음성 메시지를 주고받습니다.

 

여기서 인터페이스는 사용자가 들을 수 있는 스피커와 다른 사용자에게 음성 메시지를 전달하는 마이크,

 

그리고 기지국과 통신하는 안테나 이렇게 있다고 생각할 수 있습니다.

 

한쪽에서 다른 한쪽으로만 데이터를 줄 수도 있지만, 양쪽에서 데이터를 서로 주고받을 수 있습니다.

 

인터페이스란 결국 양쪽이든 한쪽이든 서로 연결하는 접점을 나타냅니다.

 

- 사용법

//선언 방법

/**
 * 접근 제어자(public)
 * 타입 (interface)
 * 타입명 (Speed)
 */
public interface Speed {

    /**
     * 인터페이스는 기본적으로 추상화라는 개념을 사용합니다.
     * 구현체(구현부)가 없이 속성과 메서드만 정의해서 사용할 수 있습니다.
     *
     * 구현체(구현부)란 아래와 같다.
     * void speedUpDown(){
     *
     * }
     * 이런식으로 중괄호를 만들어서 안에 구현할 내용을 만들게 되면 컴파일 에러가 난다.(참고!!)
     */

    //속성
    public static final int speed1 = 10;

    static final int speed2 = 20;

    final int speed3 = 30;

    int speed4 = 40;


    //메서드
    public abstract void speedUp1();

    abstract void speedUp2();

    void speedUp3();

}

기본 형태는 위와 같습니다.  인터페이스는 기본적으로 추상화라는 개념을 사용합니다.

 

추상화라는 개념은 제가 다루지 않았는데요 간단하게 설명을 하면 아무 기능을 정의하지 않은 상태라고 생각하면 됩니다.

 

즉, 아무 기능을 정의하지 않은 속성(필드 변수)과, 기능(메서드)을 말할 수 있습니다.

 

- 속성 규칙

속성 규칙은 public static final이라는 타입이 기본적으로 포함됩니다.

 

int speed라는 속성을 정의했다면, 앞에 public static final이라는 타입 값이 붙게 됩니다. (int speed라고만 선언해도 됩니다.)

 

- 메서드 규칙

메서드 규칙은 public abstract이라는 타입이 기본적으로 포함됩니다.

 

void speedUpDown();이라고 메서드를 정의했다면, 앞에 public abstract이라는 타입 값이 붙게 됩니다. (void speedUpDown();라고만 선언해도 됩니다.)

 

자바 8 버전부터는 defaulte와 static 메서드가 생겼습니다.

 

defaulte 메서드는 재 정의가 가능하지만 static 메서드는 재 정의가 불가능합니다.

 

- 호출 방법

인터페이스(Interface)는 extends와 implements라는 키워드를 통해 연결할 수 있습니다.

 

  • implements

    implements는 원하는 클래스 뒤에 extends가 아닌 implements라는 키워드로 선언해서 연결할 수 있습니다.



위 빨간 줄은 해당 인터페이스를 만들 때 선언했던 메서드를 해당 클래스가 선언하지 않아서 나는 에러입니다.

 

빨간 전구 모양을 클릭하면 위 이미지처럼 Implement methods를 클릭해서 메서드를 만들 수 있습니다.

 

Methods 선언
선언 결과

해당 메서드가 @Override 형태에 메서드로 만들어진 걸 확인할 수 있습니다.

 

  • extends

    인터페이스를 사용할 때 해당 키워드는 클래스가 아닌 인터페이스와 인터페이스를 연결할 때 사용됩니다.

       

extends 사용 인터페이스 연결

위와 같이 사용하면 Shoes라는 인터페이스가 다른 인터페이스 기능들을 상속받습니다.

 

Shoes 인터페이스 연결

여러 개를 하지 않고 하나만 연결해서 사용합니다.

 

선언 결과

당연히 Shoes 인터페이스에는 Speed, Slow, Stop 인터페이스 연결했기 때문에 Shoes 인터페이스를 연결하면

 

위와 같이 모든 메서드를 선언해야 합니다.

 

- 인터페이스 사용 이유

자바에서 메서드(Method)는 기능을 담당합니다.

 

특정 기능을 한 곳에서 사용한다면 그 부분에만 선언해서 사용하면 되겠지만, 우리는 프로그래밍을 하다 보면 다양한 상황을 만나게 됩니다.

 

인터페이스는 추상적인 메서드를 선언하고, 이런 인터페이스를 여러 클래스에 선언하거나 다른 인터페이스에 선언해 다양하게 사용할 수 있습니다.

 

즉, 공통적인 목적을 가진 메서드를 정의하고 그리고 공유하며 그 안에 내용을 각각 따로 선언에 사용할 수 있게 되는 겁니다.

 

이런 생각은 지극히 저에 생각입니다. 제가 개발을 하면서 느꼈던 점이기 때문에 여러분들도 꼭 실습을 통해 많은 것을 느꼈으면 좋겠습니다.