ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java] Abstract Class(추상 클래스)와 Interface(인터페이스)의 차이
    Programming/Java 2021. 8. 15. 16:55

    https://pediaa.com/wp-content/uploads/2018/09/Difference-Between-Abstract-Class-and-Interface-in-Java-Comparison-Summary.jpg

    객체지향에 있어서 Abstraction(추상화)는 단순한 인터페이스를 통해 구현의 복잡성을 숨기고 기능을 제공할 수 있는 핵심 개념이다.

    Java에서 추상화는 주로 Interface(이후 인터페이스)와 Abstract Class(이후 추상클래스)를 통해 구현할 수 있다

     

    1. Class와 Interface

    Class: 객체를 생성하기 위해 변수와 메소드를 정의하는 사용자 정의 타입. 상태와 행동을 결정하는 property와 method들로 이루어져 있다
    Interface: 클래스와 유사하지만 필드 상수와 메소드 정의부를 가지고 있는 사용자 정의 타입. 인터페이스 내의 모든 메소드는 구현체를 포함할 수 없음(Java 8미만. 8 이후 부터는 default와 static 메소드에 한해 구현체를 가질 수 있다)

     

    2. Abstract Class 🆚 Interface

      Abstract Class Interface
    사용 가능 변수 final, non-final, static, non-static variables static, final
    사용 가능 접근 제어자 제한 없음 public
    사용 가능 메소드 abstract method, non-abstract method abstract method
    상속 키워드 extends implements
    다중 상속 가능 여부 불가능 가능 ( ex. A class implements B, C )
    사용 키워드 abstract interface
    공통점 1. 인스턴스화 할 수 없다
    ➡ new TypeName()을 사용할 수 없다
    ➡ 인터페이스 혹은 추상 클래스를 상속받아 구현한 구현체의 인스턴스를 사용한다 (혹은 위와 같은 명령문을 사용할 경우 Anonymous Class를 사용하여 모든 메소드를 재정의 해야 한다)

    2. 구현 여부에 관계 없이 선언 및 정의된 메소드 집합을 포함할 수 있다

     

    3. Interface를 사용할 때

    • 다중 상속을 사용(Java에서는 기본적으로 다중 상속을 지원X)해야 할 때
    • 관련성이 없는 클래스가 인터페이스를 구현할 때 (ex. compareTo()를 사용하기 위한 Comparable interface 구현)
    • 어플리케이션의 기능을 정의해야 하지만 그 구현 방식이나 대상에 대해 추상화 할 때
    • HAS - A의 관계일 때

     

    public interface Sender {
        void send(File fileToBeSent);
    }
    public class ImageSender implements Sender {
        @Override
        public void send(File fileToBeSent) {
            // image sending implementation code.
        }
    }
    @Test
    void givenImageUploaded_whenButtonClicked_thenSendImage() { 
     
        File imageFile = new File(IMAGE_FILE_PATH);
     
        Sender sender = new ImageSender();
        sender.send(imageFile);
    }

    위의 예시에서는 "Sender가 파일을 전송할 수 있다"라는 행동을 정의할 때, 인터페이스를 사용했다.

    ImageSender 클래스는 Sender 인터페이스를 구현하여 이미지 전송 비즈니스 로직을 구현할 수 있고, VideoSender / DocumentSender와 같이 다양한 작업들이 인터페이스 구현을 통해 만들어질 수 있다.

     

    Interface는 부모-자식 관계로 연관된 상속이 아니라 Abstract Method를 정의하고 오버라이딩을 통해 여러 가지 형태로 구현할 수 있는 다형성의 개념에 더 가깝다.

    하지만 인터페이스의 특성 상 인터페이스를 구현하는 하위 클래스는 모든 추상 메소드를 구현해야 하는 강제성을 가지기 때문에, 공통된 기능(만약 존재한다면) 또한 일일히 구현해야 하는 번거로움이 생긴다.

     

    4. Abstract Class를 사용할 때

    • 하위 클래스가 오버라이드하여 재정의하는 기능들을 공유하기 위한 상속 개념을 사용할 때(많은 연관된 클래스들 간에 코드를 공유)
    • 요구사항과 함께 구현 세부 정보의 일부 기능만 지정했을 때
    • 인스턴스의 상태를 수정하기 위해 non-final / non-static 메소드를 사용해야 할 때
    • IS - A 관계일 때

     

    public abstract class Vehicle {
        
        protected abstract void start();
        protected abstract void stop();
        protected abstract void drive();
        protected abstract void changeGear();
        protected abstract void reverse();
        
        // standard getters and setters
    }
    public class Car extends Vehicle {
    
        @Override
        protected void start() {
            // code implementation details on starting a car.
        }
    
        @Override
        protected void stop() {
            // code implementation details on stopping a car.
        }
    
        @Override
        protected void drive() {
            // code implementation details on start driving a car.
        }
    
        @Override
        protected void changeGear() {
            // code implementation details on changing the car gear.
        }
    
        @Override
        protected void reverse() {
            // code implementation details on reverse driving a car.
        }
    }
    @Test
    void givenVehicle_whenNeedToDrive_thenStart() {
    
        Vehicle car = new Car("BMW");
    
        car.start();
        car.drive();
        car.changeGear();
        car.stop();
    }

    Abstract Class는 부모-자식 간의 연관성을 갖는 상속 관계에서 공통된 기능을 구현하고, 확장하는 데에 사용된다.

     

    5. Interface 🆚 Abstract Class 예시

    이 그림을 보면, Animal과 Fish는 Creature를 상속 받는다. Creature가 가지고 있는 공통 메소드에는 숨쉬기, 먹기 등이 있을 것이다.

    하지만 그 구현 방법은 Animal과 Fish가 다르기 때문에(아가미, 폐 호흡) Abstract Method로 정의하여 하위 클래스에게 상속해줄 수 있다.

    각각의 클래스에서 Abstract Method를 구체화 해준 뒤 실제 Class가 다시 상속받을 수 있다. Abstract Class는 이와 같이 상속 관계를 표현한다.

     

    사람과 호랑이는 뛰는 방식이 이족보행/사족보행으로 다르고, 사람과 고래는 지느러미를 이용한 수영/팔을 이용한 수영 등으로 기능을 구현하는 방식이 모두 다르다.

    이처럼 인터페이스는 상속의 개념과 관계 없이 각각의 공통된 특성을 추상화한 뒤 구현하는 클래스에게 제공한다. 

     

     

    참고 사이트
    - https://www.baeldung.com/java-interface-vs-abstract-class
    - https://myjamong.tistory.com/150
    - https://velog.io/@gillog/Java-Interface-vs-Abstract-Class-%EC%A0%95%EB%A6%AC
Designed by Tistory.