추상화는 공통의 속성이나 기능을 모아 추출하는 것을 뜻한다.
자바에서는 주로 추상 클래스와 인터페이스라는 문법 요소를 사용해서 추상화를 구현한다.
추상 클래스를 먼저 보자.
추상 클래스에서는 abstract 제어자를 사용한다.
자바에서 제어자는 크게 접근 제어자와 기타 제어자로 구분된다.
abstract 제어자는 기타 제어자에 속한다.
abstract 제어자는 주로 클래스와 메서드에 붙는다. 각각 추상 메서드, 추상 클래스라고 부른다.
어떤 클래스에 추상 메서드가 포함되면, 자연스레 그 클래스는 추상 클래스가 된다.
위와 같이, 추상 메서드는 메서드 바디가 없다. 또, 추상 클래스는 최소 하나 이상의 추상 메서드를 가져야 한다.
그리고, 추상 클래스는 확장된 클래스에서 메서드 바디가 완성되기 전까지는 자신을 기반으로 객체 생성이 불가하다.
추상 클래스는 상속 관계에 있어서 새로운 클래스를 만드는 데에 매우 유용하다.
상위 클래스를 구체화시켜서 구현하지 않아도, 하위 클래스에서 구체화하면 되고, 이는 설계하는 상황에서 변화가 생겨도 유연하게 대처할 수 있는 장점이 있다.
하위 클래스에서는 상위의 추상 메서드를 오버라이딩을 통해 구체화시킬 수 있다.
추상 클래스를 사용하는 상황에서, 하위 클래스에서 변하지 않을 멤버를 갖고 싶을 수도 있다.
이는 final 키워드를 이용해 정의해두면, 더이상 변경이 불가하고 확장이 불가한 멤버를 가질 수 있다.
추상 클래스는 일반적인 클래스와 크게 다르지 않다. 다만, 추상 메서드가 존재할 뿐이다.
그렇다면, 자바의 클래스는 단일 상속만이 가능한데, 다중 상속이 가능하게는 할 수 없을까?
이는 인터페이스로 해결이 가능하다.
인터페이스는 기본적으로 추상 메서드와 상수(변하지 않는 수)만을 멤버로 가질 수 있고, 추상 클래스에 비해 추상화의 정도도 더 높다.
다음 코드를 통해 인터페이스의 사용 예시를 보자.
위 코드에서 생략 가능한 부분들은 컴파일러가 자동으로 추가해주기 때문에 정상 작동한다.
이렇게 생성된 인터페이스는, 다음과 같이 implements 키워드를 사용하여 다른 클래스가 구현할 수 있다.
class 클래스 implements 인터페이스 {
... // 인터페이스에서 정의된 추상메서드 구현
}
추상 클래스의 추상 메서드를 오버라이딩 하듯이, 똑같이 구현하는 클래스도 메서드 오버라이딩을 하면 된다.
특정 인터페이스를 구현한 클래스는 해당 인터페이스에 정의된 모든 추상 메서드를 구현해야 한다.
인터페이스는 역할과 구현을 분리시켜, 코드 변경의 번거로움을 최소화하고 손쉽게 사용할 수 있는 장점을 가지고 있다.
개발자의 입장에서도 개발시간을 단축시킬 수 있고, 하나의 클래스 변경이 다른 클래스에 미치는 영향을 최소화할 수 있다.
이쯤되면, 추상 클래스와 인터페이스는 모두 하위 클래스에서 추상 메서드를 구현하는 건 똑같은데, 무슨 차이가 있는걸까? 라는 의문이 들게 된다.
결론은 인터페이스와 추상 클래스는 존재 목적 자체가 다르다.
추상 클래스는 그 추상 클래스를 상속받아 기능을 확장하고 이용하는 데 목적이 있고,
인터페이스는 함수의 껍데기만 존재하고, 그걸 구현받은 클래스에서 그 껍데기인 함수를 강제하기 위함이 목적이다. 구현을 강제함으로써, 구현 객체의 같은 동작을 보장할 수 있다.
추상 클래스는 기능을 애매하게 선언해놓고, 확장된 하위 클래스에서 기능을 구체화해서 사용하고 싶을 때 사용하고,
인터페이스는 공통적인 기능을 정의해놓고, 구현된 클래스에서 기능을 구체화시켜 공통적인 기능을 사용하고 싶을 때 사용한다고 보면 편할 것 같다.
이후, 추상 클래스와 인터페이스에 대해 더 알게되는 점이 있다면 덧붙일 예정이다.
피드백 환영합니다.
'Develop > Java' 카테고리의 다른 글
break의 범위 (1) | 2022.09.13 |
---|---|
예외 정보를 얻는 방법 3가지 (0) | 2022.09.13 |
다형성(Polymorphism) (0) | 2022.09.10 |
캡슐화(Encapsulation) (0) | 2022.09.06 |
상속(Inheritance) (0) | 2022.09.06 |