hanker

JAVA - JAVA에서 인터페이스와 추상 클래스의 차이점은 무엇일까? 본문

JAVA

JAVA - JAVA에서 인터페이스와 추상 클래스의 차이점은 무엇일까?

hanker 2024. 11. 25. 00:35
반응형

Java에서 인터페이스와 추상 클래스의 차이점에 대해 알아보자.
두 개념 모두 객체 지향 프로그래밍에서 중요한 역할을 하며, 공통된 특성은 있지만, 서로 다른 사용 목적과 특징을 가지고 있다.
 
 
 

1. 개념적인 차이

 

인터페이스 (Interface)
인터페이스는 클래스가 특정 기능을 제공한다는 약속(계약)을 의미한다. 이는 클래스가 여러 상속을 지원하지 않는 Java에서 다형성을 구현하는 데 유용하며, 모든 메서드는 기본적으로 구현되지 않은 형태로 존재한다.
Java 8부터는 디폴트 메서드와 정적 메서드도 인터페이스에 정의할 수 있게 되었다.
 
 
추상 클래스 (Abstract Class)
추상 클래스는 공통적인 특성을 가진 여러 클래스들 간의 코드 재사용성을 높이기 위해 사용된다.
추상 클래스는 일부 구현된 메서드와 추상 메서드를 함께 가질 수 있어, 자식 클래스들이 상속받아 구체화할 수 있다.
 
 
 

2. 선언 방법과 사용법

 

인터페이스의 선언 방법
인터페이스는 interface 키워드를 사용하여 선언하며, 모든 메서드는 기본적으로 public abstract이다.
인터페이스는 다중 구현을 지원하여 클래스가 여러 기능을 혼합할 수 있다.

public abstract class Developer {
    String name;

    // 생성자: 모든 Developer 객체는 이름을 가진다.
    public Developer(String name) {
        this.name = name;
    }

    // 일반 메서드: 모든 Developer는 코드를 작성한다.
    public void writeCode() {
        System.out.println(name + " is writing code.");
    }

    // 추상 메서드: 구체적인 개발자마다 다른 작업을 수행한다.
    public abstract void performTask();  // 추상 메서드
}

 
 

추상 클래스의 선언 방법
추상 클래스는 abstract 키워드를 사용하여 선언되며, 하나 이상의 추상 메서드를 포함할 수 있다.
하지만 추상 클래스는 일반 메서드와 필드도 포함할 수 있다.

public abstract class TestAbstractClass {
    String name;
    
    // 생성자
    public TestAbstractClass(String name) {
        this.name = name;
    }
    
    // 일반 메서드
    public void testing() {
        System.out.println(name + " is testing");
    }
    
    // 추상 메서드
    public abstract void test();
    
}

 
 
 

3. 다중 상속의 지원

 

인터페이스의 다중 상속
인터페이스는 다중 상속이 가능하다. 
하나의 클래스는 여러 인터페이스를 구현할 수 있어 다양한 기능을 결합할 수 있다.

public class FullStackDeveloper extends Developer implements Debuggable {
    
    // FullStackDeveloper 생성자: 이름을 받아 상위 클래스인 Developer 생성자를 호출
    public FullStackDeveloper(String name) {
        super(name);
    }

    // 추상 클래스 Developer의 추상 메서드 구현: FullStackDeveloper는 여러 작업을 수행
    @Override
    public void performTask() {
        System.out.println("FullStackDeveloper is developing full-stack features.");
    }

    // 인터페이스 Debuggable의 추상 메서드 구현: FullStackDeveloper는 디버깅을 수행
    @Override
    public void debug() {
        System.out.println(name + " is debugging the application.");
    }
}

 
 
추상클래스의 다중 상속
추상 클래스는 단일 상속만 지원한다. 즉, 한 클래스는 단 하나의 추상 클래스만 상속할 수 있다.

abstract class Developer {
    abstract void performTask();
}

abstract class Designer {
    abstract void createDesign();
}

// 다중 상속을 시도하는 클래스 (컴파일 오류 발생)
public class FullStackCreator extends Developer, Designer {  // 오류: Java는 다중 상속을 지원하지 않음
    @Override
    void performTask() {
        System.out.println("FullStackCreator performing development task");
    }

    @Override
    void createDesign() {
        System.out.println("FullStackCreator creating design");
    }
}

Java 에서는 한 클래스가 여러 개의 부모 클래스를 상속받을 수 없다. 이는 다중 상속으로 인해 발생할 수 있는 모호성과 충돌을 방지하기 위함이다.
 

반응형

 

4. 필드의 사용 여부

 

인터페이스의 필드 사용
인터페이스는 Java 8 이전까지 필드를 가질 수 없었고, 상수(public static final) 만 정의할 수 있었는데, Java 8 이후에는 인터페이스 내에서 정적 메서드 및 디폴트 메서드를 정의할 수 있게 되었지만, 여전히 필드의 상태를 저장하는 것은 불가능하다.

public interface Configurable {
    // 인터페이스 내의 필드는 기본적으로 public static final로 정의된다.
    String CONFIG_FILE_PATH = "/etc/config/default.conf";

    // 추상 메서드: 모든 Configurable 객체는 설정을 로드해야 한다.
    void loadConfig();

    // 정적 메서드: 인터페이스 수준에서 설정 경로를 출력할 수 있다.
    static void printConfigPath() {
        System.out.println("printConfigPath() : " + CONFIG_FILE_PATH);
    }
}

class Application implements Configurable {
    @Override
    public void loadConfig() {
        System.out.println("loadConfig() : " + CONFIG_FILE_PATH);
    }
}

class Main {
    public static void main(String[] args) {
        Application app = new Application();
        app.loadConfig();
        Configurable.printConfigPath();
    }
}

 
 
추상 클래스의 필드 사용
추상 클래스는 필드를 가질 수 있으며, 접근 제어자(privateprotectedpublic)를 통해 필드에 접근을 제한할 수 있습니다.
 
 
 
 

5. 목적과 사용

 
인터페이스의 목적과 사용 사례
인터페이스는 서로 다른 클래스들이 같은 기능을 수행하도록 만들 때 사용된다.
예를 들어, Debuggable, Testable 같은 기능성 인터페이스는 다양한 클래스에 구현되어 각기 다른 클래스들이 동일한 기능을 제공할 수 있도록 한다.
 
 
추상 클래스의 목적과 사용 사례
추상 클래스는 서로 관련된 클래스들이 공통적인 동작을 공유할 때 사용된다.
예를 들어, 다양한 개발자 클래스가 공통적으로 사용하는 메서드와 필드를 추상 클래스로 정의할 수 있다.
 
 
 

6. 정리

 

- 추상 클래스는 클래스 계층에서 공통된 특성을 정의하고 일부 메서드를 구현할 때 사용
- 인터페이스는 클래스에 기능을 부여하고 다중 구현이 가능
- 추상 클래스는 단일 상속만 가능하며, 인터페이스는 다중 상속이 가능
- Java 8 이후에는 인터페이스에 default 메서드와 static 메서드를 포함할 수 있게 되었습니다.
 
 
추상 클래스와 인터페이스는 Java의 강력한 객체 지향 기능을 제공하며, 각 상황에 따라 적절히 사용하여 코드의 유연성과 재사용성을 높일 수 있다.

반응형