Java (추상 클래스 Abstract Class)

최병현·2026년 1월 7일

java

목록 보기
27/38

추상 클래스(Abstract Class) 정리

이 내용은 Backend/OOP logic in Java 영역(객체지향 설계)에서 쓰이는 개념이다. 추상 클래스는 “상속을 전제로 한 설계 도구”로, 공통 기능은 부모(추상 클래스)에 모으고, 자식 클래스가 반드시 구현해야 할 규칙(추상 메서드)을 강제하는 역할을 한다.


1. 추상(Abstract)의 의미

abstract는 “추상적인”이라는 뜻이고, 자바에서는 구현이 없는 메서드(추상 메서드)를 만들 수 있게 해준다.


2. 정의

  • 추상 메서드(abstract method): 선언만 있고 구현(body)이 없는 메서드
  • 추상 클래스(abstract class): 추상 메서드를 하나 이상 포함하는 클래스

그리고 중요한 차이: 추상 클래스는 객체를 직접 생성할 수 없다. (즉, new Factory() 같은 직접 인스턴스화가 원칙적으로 불가능)


3. 일반 메서드 vs 추상 메서드 구조

일반 메서드는 구현부가 있다.

// 일반 메서드 (implementation exists)
public void showInfo() {
    System.out.println("My name is " + name + ".");
}

public double calcAvg(double[] scores) {
    double sum = 0;
    for (double score : scores) {
        sum += score;
    }
    return sum / scores.length;
}

추상 메서드는 선언만 있고 구현부가 없다.

// 추상 메서드 (declaration only)
public abstract void showInfo();
public abstract double calcAvg(double[] scores);

4. 추상 클래스의 목적

  • 공통 기능 제공: 여러 자식 클래스에서 공통으로 쓰는 field/method를 부모에서 제공
  • 구체적인 구현 강제: 추상 메서드를 통해 자식이 “반드시 구현해야 하는 기능”을 강제
  • 코드 재사용성 향상: 중복을 줄여 유지보수가 쉬워짐

5. 주의사항

  • 추상 클래스는 객체 생성을 못한다.
  • 단, 예외적으로 익명 클래스(anonymous class)로 “즉석 구현”을 붙이면 임시 객체 생성이 가능하다.
  • 익명 클래스는 “한 번만 쓰고 버릴 구현”에 적합하며, 이후에는 Lambda Expression 등으로 대체되는 경우가 많다.

6. 예제 코드

아래 예제는 Factory를 추상 클래스로 만들고, produce(), manage()를 자식 클래스에서 반드시 구현하도록 강제한다.

/*
  Backend/OOP logic in Java: Abstract Class + Abstract Method + Override + Anonymous Class
*/

public abstract class Factory {
    // field
    private String name;

    // abstract methods (must be implemented by subclasses)
    public abstract void produce(String model);
    public abstract void manage();

    // getter / setter
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // concrete method (reusable common behavior)
    public void showInfo() {
        System.out.println("Factory info\nFactory name: " + name);
    }
}

public class PhoneFactory extends Factory {

    @Override
    public void produce(String model) {
        System.out.println("Phone factory: " + getName() + " produces [" + model + "]");
    }

    @Override
    public void manage() {
        System.out.println("Managing phone factory.");
    }
}

public class TableFactory extends Factory {

    @Override
    public void produce(String model) {
        System.out.println(getName() + " produces [" + model + "]");
    }

    @Override
    public void manage() {
        System.out.println("Managing tablet factory.");
    }

    public void upgrade(String model) {
        System.out.println("Upgrading to " + model);
    }

그리고 아래는 “추상 클래스는 원래 객체 생성이 안 되지만”, 익명 클래스를 이용하면 그 자리에서 구현을 붙여 임시 인스턴스를 만들 수 있다는 예시다.

public class FactoryMain {
    public static void main(String[] args) {

        // Anonymous class: temporary implementation for abstract class
        Factory factory1 = new Factory() {
            @Override
            public void produce(String model) {
                System.out.println(getName() + " produces [" + model + "]");
            }

            @Override
            public void manage() {
                System.out.println("Managing home appliance factory.");
            }
        };

        factory1.setName("Temp Factory");
        factory1.produce("Monitor");
        factory1.manage();
        factory1.showInfo();

        System.out.println("---------------------------------------------");

        PhoneFactory phoneFactory1 = new PhoneFactory();
        phoneFactory1.setName("Apple Phone Factory");
        phoneFactory1.produce("iPhone Air2");
        phoneFactory1.manage();
        phoneFactory1.showInfo();

        System.out.println("---------------------------------------------");

        TableFactory tableFactory1 = new TableFactory();
        tableFactory1.setName("Google Tablet Factory");
        tableFactory1.produce("Pixel Tablet");
        tableFactory1.manage();
        tableFactory1.upgrade("Pixel Tablet Gen2");

        System.out.println("---------------------------------------------");

        Factory factory2 = new Factory() {
            @Override
            public void produce(String model) {
                System.out.println("Producing computer: " + model);
            }

            @Override
            public void manage() {
                System.out.println("Managing computer factory.");
            }
        };

        factory2.setName("Samsung Computer Factory");
        factory2.showInfo();
    }
}

7. 추가 활용 및 제약 사항

  • 추상 클래스는 “상속을 전제로” 설계된다. 즉, 자식 클래스가 추상 메서드를 구현해야 실제 객체로 사용할 수 있다.
  • 부모(Factory) 타입으로 자식을 담을 수 있어 다형성(Polymorphism) 구조로 확장하기 좋다. (예: Factory f = new PhoneFactory();)
  • 부모에 이미 구현된 일반 메서드(showInfo())가 있다면, 자식에서 중복 구현하지 말고 “그냥 재사용”하는 게 유지보수에 유리하다.

8. 정리

추상 클래스는 “객체 생성은 막고”, “상속을 통해 구현을 강제하는” OOP 설계 도구다. 공통 기능은 부모에 모아서 재사용하고, 자식 클래스가 반드시 구현해야 하는 기능은 추상 메서드로 규칙을 만들 수 있다. 단, 직접 객체 생성은 불가능하며(원칙), 필요할 때만 익명 클래스로 임시 구현을 붙여 한 번성 객체로 사용할 수 있다.

profile
Develop

0개의 댓글