개발 이야기/OOP

[OOP] 추상화(Abstraciton)란?

제이온 (J.ON) 2021. 6. 1.

안녕하세요? 제이온입니다.

 

이번 시간에는 저번 포스팅인 상속에 이어서 추상하에 대해 알아보겠습니다.

 

 

추상화란?

위키피디아에 따르면, 추상화를 아래와 같이 정의하고 있습니다.

 

 

컴퓨터 과학에서 추상화는 복잡한 자료, 모듈, 시스템 등으로부터 핵심적인 개념 또는 기능을 간추려 내는 것을 말한다.

 

 

추상화는 이처럼 구체적인 사물들간의 공통점을 취하고 차이점을 버리는 일반화를 사용하거나, 중요한 부분을 강조하기 위해 불필요한 세부 사항을 제거함으로써 단순하게 만듭니다. 결국 핵심은 불필요한 코드를 제거하고 중요한 부분을 살리는 것입니다.

 

예를 들어, for, while, do~while 등과 같은 문법은 반복문을 추상화한 것입니다. 실제로는 CPU의 명령을 통해서 반복이 구현되겠지만, 이 구현으로부터 '반복'이라는 개념을 뽑아내서 for, while, do~while 등으로 추상화한 것이죠.

 

조금 더 직관적인 예시를 들어 보겠습니다. 만약, 제가 은행 관련 애플리케이션을 만든다고 가정해 보겠습니다. 은행을 이용하는 고객의 정보가 필요할텐데, 고객의 정보라고 하면 이름, 주소, 휴대폰 번호, 주소 등이 있을 수 있습니다. 그런데, 사실 정보라는 범위가 모호하므로 위의 정보 외에도 좋아하는 음식, 취미, 특기 등까지도 포함할 수 있습니다. 다만, 은행 애플리케이션에서의 고객 정보로 좋아하는 음식, 취미, 특기는 필요하지 않습니다. 그래서 이러한 불필요한 정보를 제거함으로써 중요한 정보만 남기는 것 자체도 추상화라고 할 수 있습니다.

 

이제부터는 OOP에서의 소스 코드를 통해 추상화를 이해해 봅시다.

 

 

추상화 예제

도입부에서 추상화는 일반화를 통해서 구현될 수 있다고 하였습니다. 일반화는 구체적인 사물들간의 공통점을 취하고 차이점을 버리는 것을 말합니다. 예를 들어, 아래와 같이 SuperCar, SnowCar, FastCar가 있다고 합시다.

 

 

public class SuperCar {

    public void move() {
        System.out.println("슈퍼하게 달립니다.");
    }
}

public class SnowCar {

    public void move() {
        System.out.println("겨울에 잘 달립니다.");
    }
}

public class FastCar {

    public void move() {
        System.out.println("빠르게 달립니다.");
    }
}

 

 

그리고 이들을 움직이게 하기 위하여 사용자 입장에서는 아래와 같이 코드를 작성할 것입니다.

 

 

public class Main {

    public static void main(String[] args) {
        final SuperCar superCar = new SuperCar();
        final SnowCar snowCar = new SnowCar();
        final FastCar fastCar = new FastCar();

        superCar.move();
        snowCar.move();
        fastCar.move();
    }
}

 

 

 

 

그런데, 움직인다는 행위는 같으므로 차의 공통된 속성인 'move'를 상위 클래스로 뽑아낼 수 있습니다. 똑같은 자동차들이므로 Car라는 상위 클래스를 두어 상속 관계를 만들어도 무방할 것입니다. 이때, 저는 저번 시간에 배운 캡슐화를 지키기 위해서 추상 클래스로 만들었습니다.

 

 

public abstract class Car {

    public abstract void move();
}

public class FastCar extends Car{

    @Override
    public void move() {
        System.out.println("빠르게 달립니다.");
    }
}

public class SnowCar extends Car {

    @Override
    public void move() {
        System.out.println("겨울에 잘 달립니다.");
    }
}

public class SuperCar extends Car {

    @Override
    public void move() {
        System.out.println("슈퍼하게 달립니다.");
    }
}

 

 

그리고 하위 클래스들은 추상 메소드를 재정의하면 됩니다. 사용자 입장에서 아래와 같이 소스 코드를 작성할 수 있습니다.

 

 

public class Main {

    public static void main(String[] args) {
        final List<Car> cars = Arrays.asList(new SuperCar(), new SnowCar(), new FastCar());
        for (final Car car : cars) {
            car.move();
        }
    }
}

 

 

 

 

결과적으로 우리는 일반화를 통해 추상화를 구현하자고 생각했고, 그 목적을 위한 방식은 바로 타입입니다. 좀 더 상위 타입을 정의함으로써 추상화와 동시에 다형성을 구현할 수 있게 된 것이죠. 그리고 상위 타입의 방식으로 상속을 사용하였습니다. 더불어, 상위 타입은 추상 클래스로 선언함으로써 캡슐화까지도 지킬 수 있었습니다.

 

 

정리

예제에서는 타입과 상속을 통해 추상화를 구현하였지만, 이 방법에만 사고가 갇히시면 안 됩니다. 불필요한 것을 지우고 핵심을 남겨둔다는 추상화의 기본 사고를 기억하시면서 여러 가지 상황에 적용하시길 바랍니다.

 

 

참고 자료

 

What is Abstraction in OOPs? Java Abstract Class & Method

In this tutorial, you will learn- How to use Conditional Statements Different Types of Conditional...

www.guru99.com

 

 

 

추천 글