Java Abstract - 놓치기 쉬운 개념들

이강현·2025년 4월 9일

Abstract Method

Java 의 abstract class 혹은 interface 를 보면 추상화 기능을 메서드에서만 제공하고 있습니다.
객체의 행위는 추상화 하지만 속성은 추상화 하지 않는 이유는 다음과 같이 생각해 볼 수 있습니다.

  • 객체 지향 프로그래밍에서 중요한 것은 객체의 행위이며, 추상 메서드를 통해 다양한 하위 클래스가 동일한 인터페이스를 따르면서 각자의 방식으로 동작하도록 하는 다형성이 핵심적인 개념입니다.

  • 객체의 상태는 일반적으로 구체적이며, 하위 클래스 간에 완전히 추상화하기 어려운 경우가 많습니다. 자료형을 명시하는 것은 코드의 가독성과 안정성을 높이는 데 도움이 될 수 있습니다.

  • 다른 언어들에서 속성을 추상화 하려는 시도를 확인할 수 있습니다.
    • Kotlin 의 타입 추론으로 타입을 추상화
    • C#, Python 의 property 로 필드 접근 행위를 추상화
    • Swift 의 프로토콜로 속성 자체를 추상화



Interface - static method, default method

interface 에 추상 메서드 이외의 static method, default method를 정의할 수 있습니다.

  • interface 의 static method
    • utility method 혹은 helper method 를 제공하기 위해 사용합니다.
    • 인터페이스를 구현하는 클래스에서는 상속되지 않으므로, 클래스 이름으로 직접 호출할 수 없습니다.
      반드시 인터페이스 이름으로 호출해야 합니다. 따라서 다중상속 상황에서도 충돌 위험이 없습니다.
interface Shape {
    void draw();

    static Shape createShape(String type) {
        switch (type.toLowerCase()) {
            case "circle":
                return new Circle();
            case "rectangle":
                return new Rectangle();
            default:
                throw new IllegalArgumentException("unknown shape: " + type);
        }
    }
}
  • interface 의 default method
    • 인터페이스에 기본적인 구현을 제공하는 메서드입니다.
      인터페이스를 구현하는 클래스에서 선택적으로 override할 수 있습니다.
    • interface 의 변경에 의한 파급을 줄이는데 효과적입니다.
    • 다중 상속 상황에서 충돌이 발생하면 compiler error 가 발생하므로 반드시 override 해야합니다.
interface I {
    default void m1() {
        System.out.println("I.m1");
    }

    default void m2() {
        System.out.println("I.m2");
    }
}

class C implements I {
    // use default m1
    // but override m2
    @Override
    public void m2() {
        System.out.println("C.m2");
    }
}
interface I1 {
    default void m() {
        System.out.println("I1.m");
    }
}
interface I2 {
    default void m() {
        System.out.println("I2.m");
    }
}
class C implements I1, I2 { // same name and signature m() inherited, conflict 
    // to avoid conflict, must override
    @Override
    public void m() {
        I1.super.m();
        I2.super.m();
    }
}```
profile
백엔드 개발자 지망생입니다.

0개의 댓글