본문 바로가기

ComputerScience/Java

[Java] abstract vs interface 언제 써야하는가?

이미지 출처: https://java.tutorials24x7.com/uploads/2020-06-20/banner/interface-vs-abstract-class-java.jpg

 

디자인패턴을 공부하다 보니 어떨 땐 abstract 클래스로, 어떨 땐 interface로 구현을 하는 것을 보았는데

이 둘의 차이를 명확히 잘 몰라서 알아보았습니다.

Abstract Class와 Interface

추상클래스 (Abstract class)

 

자바에서는 하나 이상의 추상 메소드(abstract method)를 포함하는 클래스를 가리켜 추상 클래스(abstract class)라고 합니다.

 

여기서 추상 메소드란 자식 클래스에서 반드시 오버라이딩해야만 사용할 수 있는 메소드를 의미합니다.

자바에서 추상 메소드를 선언하여 사용하는 목적은 추상 메소드가 포함된 클래스를 상속받는 자식 클래스가 반드시 추상 메소드를 구현하도록 하기 위함입니다.

 

예를 들면 모듈처럼 중복되는 부분이나 공통적인 부분은 미리 다 만들어진 것을 사용하고, 이를 받아 사용하는 쪽에서는 자신에게 필요한 부분만을 재정의하여 사용함으로써 생산성이 향상되고 배포 등이 쉬워지기 때문입니다.

 

이러한 추상 메소드는 선언부만이 존재하며, 구현부는 작성되어 있지 않습니다.

바로 이 작성되어 있지 않은 구현부를 자식 클래스에서 오버라이딩하여 사용하는 것입니다.

// 추상 클래스 Animal 정의
abstract class Animal {
    abstract void makeSound(); // 추상 메소드 makeSound 정의
}

// Animal 클래스를 상속받는 Dog 클래스 정의
class Dog extends Animal {
    // 추상 메소드 makeSound를 구현
    void makeSound() {
        System.out.println("멍멍!");
    }
}

// Animal 클래스를 상속받는 Cat 클래스 정의
class Cat extends Animal {
    // 추상 메소드 makeSound를 구현
    void makeSound() {
        System.out.println("야옹!");
    }
}

// 메인 클래스
public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog(); // Dog 객체 생성
        Cat myCat = new Cat(); // Cat 객체 생성

        myDog.makeSound(); // "멍멍!" 출력
        myCat.makeSound(); // "야옹!" 출력
    }
}

 

다시 추상 클래스로 돌아와서, 추상 클래스는 인스턴스화가 될 수 없으며 이를 인스턴스화하려고 하면 에러가 발생합니다.

추상 클래스의 메서드 중에서 일부는 구현이 있을 수 있고, 나머지는 추상 클래스로 남겨질 수 있습니다. 추상 클래스는 하위 클래스에서 반드시 구현되어야 합니다. 

 

이러한 추상 클래스는 객체 지향 프로그래밍에서 중요한 특징인 다형성을 가지는 메소드의 집합을 정의할 수 있도록 해줍니다.

즉, 반드시 사용되어야 하는 메소드를 추상 클래스에 추상 메소드로 선언해 놓으면, 이 클래스를 상속받는 모든 클래스에서는 이 추상 메소드를 반드시 재정의해야 합니다.

Interface

  • Interface는 객체 생성이 불가능하며, 클래스에서 구현해야 하는 일련의 메서드를 정의합니다.
  • Interface의 메서드는 기본적으로 모두 추상 메소드이며, 구현이 없습니다.
  • interface는 오로지 추상 메소드와 상수만을 포함할 수 있습니다.
// 인터페이스 Animal 정의
interface Animal {
    void makeSound(); // 인터페이스 메소드 makeSound 정의
}

// Animal 인터페이스를 구현하는 Dog 클래스 정의
class Dog implements Animal {
    // 인터페이스 메소드 makeSound를 구현
    public void makeSound() {
        System.out.println("멍멍!");
    }
}

// Animal 인터페이스를 구현하는 Cat 클래스 정의
class Cat implements Animal {
    // 인터페이스 메소드 makeSound를 구현
    public void makeSound() {
        System.out.println("야옹!");
    }
}

// 메인 클래스
public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog(); // Dog 객체 생성
        Cat myCat = new Cat(); // Cat 객체 생성

        myDog.makeSound(); // "멍멍!" 출력
        myCat.makeSound(); // "야옹!" 출력
    }
}

 

하지만 java 8 이후로 default 키워드를 사용하여 구현이 있는 인터페이스 메소드를 만들 수 있습니다.

interface Drawable{  
	void draw();  
	default void msg(){System.out.println("default method");}  
}  
class Rectangle implements Drawable{  
	public void draw(){System.out.println("drawing rectangle");}  
}  
class TestInterfaceDefault{  
	public static void main(String args[]){  
        Drawable d=new Rectangle();  
        d.draw();  
        d.msg();  
	}
}

Output

drawing rectangle
default method

 

또한 Static으로도 선언 가능합니다.

interface Drawable{  
    void draw();  
    static int cube(int x){return x*x*x;}  
}  
class Rectangle implements Drawable{  
	public void draw(){System.out.println("drawing rectangle");}  
}  
  
class TestInterfaceStatic{  
    public static void main(String args[]){  
        Drawable d=new Rectangle();  
        d.draw();  
        System.out.println(Drawable.cube(3));  
	}
}

Output

drawing rectangle
27

둘의 차이점

접근 제어자 (Access Modifiers)

  • 추상 클래스는 메서드와 속성에 대해 public, protected, private과 같은 접근 제어자를 가질 수 있습니다. 
  • 그러나 인터페이스의 메서드는 기본적으로 public이며, 다른 접근 제어자를 가질 수 없습니다.

상속 (Inheritance)

  • 하나의 클래스는 하나의 추상 클래스만 상속 가능합니다.
  • 하나의 클래스는 여러 인터페이스를 구현할 수 있습니다.

변수 (Variables)

  • 추상 클래스는 멤버 변수를 가질 수 있습니다.
  • 인터페이스는 멤버 변수를 가질 수 없습니다.

요약하면, 추상 클래스는 구체적인 서브클래스가 상속받을 기본 클래스를 제공하는 데 사용되며, 

반면에 인터페이스는 클래스가 반드시 구현해야 하는 메서드 집합을 정의하는 데 사용됩니다. 

추상 클래스는 구현된 메서드와 추상 메서드를 가질 수 있지만, 인터페이스는 오직 추상 메서드만을 가질 수 있습니다. 또한, 클래스는 하나의 추상 클래스만을 상속할 수 있지만, 여러 인터페이스를 동시에 구현할 수 있습니다.

추상 클래스의 특징

1. 직접 인스턴스화 불가능

- 추상 클래스는 직접적으로 객체를 생성할 수 없습니다. 다시 말해, 추상 클래스로부터 직접 객체를 만들 수는 없습니다.

 

2. 최소한 하나의 순수 가상 함수 포함

- 추상 클래스는 최소한 하나 이상의 순수 가상 함수(pure virtual function)를 포함해야 합니다.

- 순수 가상 함수는 구현이 없는 함수로, 해당 함수는 파생 클래스에서 반드시 구현되어야 합니다.

 

3. 추상 및 비추상 메서드 모두 포함 가능

- 추상 클래스는 추상 메서드뿐만 아니라 비추상 메서드도 포함할 수 있습니다. 비추상 메서드는 완전한 구현을 가지며 직접 호출될 수 있습니다.

 

4. 생성자와 소멸자 포함 가능

- 추상 클래스는 생성자와 소멸자를 포함할 수 있습니다. 이는 다른 클래스와 마찬가지로 객체의 초기화 및 정리를 위해 사용됩니다.

 

5. 멤버 변수 포함 가능

- 추상 클래스는 멤버 변수를 가질 수 있습니다. 이는 해당 클래스의 객체에 속하는 변수들을 말합니다.

 

6. 기본 클래스로 사용 가능

- 추상 클래스는 다른 클래스의 기본 클래스로 사용될 수 있습니다. 즉, 다른 클래스에서 상속받을 수 있습니다.

인터페이스의 특징 

1. 메서드 및 속성 정의

    - 인터페이스는 어떠한 클래스나 구조체가 해당 인터페이스를 구현할 때 반드시 가져야 하는 메서드와 속성들을 정의합니다.

 

2. 공통 프로토콜 제공

   - 인터페이스는 서로 다른 소프트웨어 컴포넌트 간에 통신할 수 있는 공통 프로토콜을 제공합니다.

 

3. 다형성 지원

   - 인터페이스는 다형성을 구현하는 데 사용될 수 있습니다. 다양한 클래스의 객체들이 동일한 타입으로 취급될 수 있게끔 하는 기능입니다.

 

4. 관심사 분리

   - 인터페이스는 관심사를 분리함으로써, 소프트웨어 시스템의 여러 부분이 독립적으로 개발될 수 있도록 합니다.

 

5. 코드 재사용성 향상

   - 인터페이스는 동일한 인터페이스를 구현하는 다양한 소프트웨어 컴포넌트가 동일한 코드 베이스를 재사용할 수 있게끔 합니다.

 

6. 디자인 패턴 강화

   - 인터페이스는 특정 디자인 패턴을 강제함으로써, 특정 메서드나 속성이 반드시 구현되도록 할 수 있습니다. 예를 들면 어댑터 패턴(Adapter Pattern) 등이 있습니다.

 

7. 테스트 용이성 촉진

   - 인터페이스는 테스트를 쉽게 할 수 있도록 도와줍니다. 인터페이스를 구현하는 가짜 객체(mock objects)를 사용하여 소프트웨어 컴포넌트를 독립적으로 테스트할 수 있습니다.

그래서, 언제 언제 사용해야 하는데?

(이 글을 작성하게 된 계기.. 각각 언제 사용해야 하는가입니다.)


추상 클래스를 사용해야 하는 경우

 

1. Java 애플리케이션에서 관련된 클래스들이 일부 코드를 공유해야 하는 상황이 있다면, 이 코드들을 추상 클래스 내에 넣고 이 추상 클래스를 관련 클래스들이 상속하도록 할 수 있습니다.


2. 추상 클래스 내에 비정적 또는 변경 가능한 필드를 정의하여, 이 필드들에 대한 상태를 수정하고 액세스 하는 메서드를 통해 해당 객체의 상태를 조작할 수 있습니다.


3. 추상 클래스를 상속하는 클래스들이 많은 공통 메서드 또는 필드를 가지거나, public 이외의 접근 제어자 (protected 및 private와 같은)가 필요한 경우 사용될 수 있습니다.


인터페이스를 사용해야 하는 경우

 

1. 전체적인 추상화가 필요하며, 인터페이스 내에서 선언된 모든 메서드는 해당 인터페이스를 구현하는 클래스에 의해 반드시 구현되어야 하는 경우 사용될 수 있습니다.


2. 클래스는 여러 인터페이스를 구현할 수 있는 다중 상속이 필요한 경우 사용될 수 있습니다.


3. 특정 데이터 유형의 동작을 지정하고, 해당 동작을 구현하는 클래스가 누구인지에 대한 고려가 필요하지 않은 경우 사용될 수 있습니다.

참고 자료

https://www.geeksforgeeks.org/difference-between-abstract-class-and-interface-in-java/

 

Difference between Abstract Class and Interface in Java - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

https://tcpschool.com/java/java_polymorphism_interface

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com