추상화(Abstraction)는 복잡한 시스템에서 핵심적인 부분만을 추려내어 단순화하는 것. 즉, 필요한 기능만 보여주고, 불필요한 구현 세부사항은 숨기는 것.
사용자는 어떤 기능이 무엇을 하는지만 알면 되고, 어떻게 동작하는지는 몰라도 된다는 개념이다.
전자레인지를 사용할 때 내부에서 마이크로파가 어떤 주기로 작동하는지, 회로가 어떻게 구성되어 있는지 몰라도 버튼만 누르면 요리가 되는 것처럼, 자바에서도 필요한 인터페이스만 제공하고, 내부 구현은 숨길 수 있다.
자바에서는 두 가지 방법으로 추상화를 구현할 수 있다:
추상 클래스 (abstract class)
인터페이스 (interface)
추상 클래스는 일부 메서드는 구현하고, 일부는 추상 메서드(구현되지 않은 메서드)로 선언해 서브클래스가 반드시 구현하도록 강제할 수 있다.
abstract class Animal {
String name;
Animal(String name) {
this.name = name;
}
// 추상 메서드 (하위 클래스가 반드시 구현해야 함)
abstract void makeSound();
// 일반 메서드
void eat() {
System.out.println(name + " is eating.");
}
}
class Dog extends Animal {
Dog(String name) {
super(name);
}
@Override
void makeSound() {
System.out.println("멍멍!");
}
}
Animal dog = new Dog("초코");
dog.eat(); // 초코 is eating.
dog.makeSound(); // 멍멍!
인터페이스는 모든 메서드가 기본적으로 추상 메서드이며, 다중 구현이 가능하다는 장점이 있다. 기능 위주의 설계에 유용하다.
interface RemoteControl {
void turnOn();
void turnOff();
}
class TV implements RemoteControl {
public void turnOn() {
System.out.println("TV를 켭니다.");
}
public void turnOff() {
System.out.println("TV를 끕니다.");
}
}
RemoteControl rc = new TV();
rc.turnOn(); // TV를 켭니다.
rc.turnOff(); // TV를 끕니다.
복잡성을 줄인다: 핵심 기능만 공개하므로 사용이 간편해짐
유지보수가 쉬워진다: 구현이 바뀌어도 인터페이스는 동일
유연한 구조 설계: 다양한 구현체를 만들어 교체할 수 있음
표준화된 설계: 인터페이스를 기준으로 코딩하면 팀원 간 작업 분담이 쉬워짐
공통된 기능을 공유하지만, 세부 구현이 다른 객체들을 다룰 때
인터페이스를 기반으로 다형성을 활용하고 싶을 때
개발 초기 단계에서 구조를 먼저 정의하고 싶을 때
자바에서의 추상화는 복잡한 세계를 단순화하고, 유연한 시스템을 설계하는 핵심 기술. 추상 클래스와 인터페이스는 각각의 장단점이 있으므로 상황에 맞게 사용하는 것이 중요하다.