[JAVA] 추상 클래스와 인터페이스

이재훈·2023년 8월 7일
0

JAVA8

목록 보기
18/22

자바와 객체지향

추상 클래스와 인터페이스

추상화 ? abstract

공통의 속성이나 기능을 묶어 이름을 붙이는 것, 객체 지향 관점에서 클래스를 정의 하는 것을 추상화라고 할 수 있습니다.

추상화가 안된 객체지향적이지 않은 코드를 보겠습니다.

public class Client {
    public void SomeMethod() {
        FakeMessageSender fakeMessageSender = new FakeMessageSender();
        fakeMessageSender.send();
    }
}

class RealMessageSender {
    public void send() {
        // 실제 메시지 보내는 기능
    }
}

class FakeMessageSender {
    public void send() {
        // 메시지는 안 보내고 메시지를 보냈다는 로그 찍기
    }
}

위 코드는 Client가 메시지를 보내는 기능을 테스트, 또는 실제 메시지를 보내는 것을 구현한 것입니다. Client 가 해당 기능들을 사용하려면 직접 객체를 생성하여 메서드를 호출해야 합니다.

FakeMessageSender의 send메서드를 사용하다가 RealMessageSender의 send 메서드를 사용하려고 한다면 Client의 코드가 변경되어야 합니다.

public class Client {
    private final MessageSender messageSender;

    Client(MessageSender messageSender) {
        this.messageSender = messageSender;
    }

    public void SomeMethod() {
        messageSender.send();
    }
}

interface MessageSender {
    void send();
}

class RealMessageSender implements MessageSender{
    public void send() {
        // 실제 메시지 보내는 기능
    }
}

class FakeMessageSender implements MessageSender{
    public void send() {
        // 메시지는 안 보내고 메시지를 보냈다는 로그 찍기
    }
}

인터페이스를 사용하여 Client는 더 이상 FakeMessageSender와 RealMessageSender에 의존적이지 않습니다. MessageSender는 다형성을 제공해주는 추상적인 존재이고 저희는 가급적 인터페이스 같은 추상적인 존재에 의존하도록 코드를 작성해야 합니다.

추상 클래스

public abstract class AbstractClass {
    public void implementedMethod() {
        System.out.println("AbstractClass implementedMethod");
        this.abstractMethod();
    }

    abstract public void abstractMethod();
}

class ExtendedClass extends AbstractClass {

    @Override
    public void abstractMethod() {
        System.out.println("ExtendedClass abstractMethod");
    }
}
추상 클래스는 인스턴스를 생성할 수 없습니다.
일반적으로 하나 이상의 추상 메서드를 포함합니다.

추상 클래스에 구현된 메서드 안에서 구현되지 않은 abstract 메서드를 호출할 수 있다는 점을 확인 할 수 있습니다. 이 문법은 강력한 추상화 문법입니다.
공통된 로직은 추상 클래스에 미리 정의해두고 각각의 구현 클래스에서 달라져야 하는 부분만 abstract 메서드를 구현하여 사용할 수 있습니다.

인터페이스

interface SomeInterface {
    void someMethod();
    
    default void defaultMethod() {
    	this.someMethod();
    }
}

interface AnotherInterface {
    void anotherMethod();
}

class ImplementsClass implements SomeInterface, AnotherInterface {
    @Override
    public void someMethod() {
        System.out.println("someMethod");
    }

    @Override
    public void anotherMethod() {
        System.out.println("anotherMethod");
    }
}
클래스는 하나만 상속 받을 수 있습니다.
인터페이스는 여러 개 구현이 가능합니다.

인터페이스를 구현하는 클래스는 해당 인터페이스가 가지고 있던 메서드를 반드시 구현해야 합니다.

인터페이스에서 메서드 앞에 default 키워드를 넣게 되면 default 메서드입니다. default 메서드는 인터페이스에도 메서드를 정의할 수 있게 해줍니다. (JAVA8 이후 가능)

추상 클래스와 인터페이스가 무엇이 다를까?

문법적으로는 비슷하다 할 수 있지만 사용하는 상황이 다릅니다.

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

  • 인스턴스 변수(필드)가 필요한 경우
  • 생성자가 필요한 경우
  • Object 클래스의 메서드를 오버라이딩 하고 싶은 경우

이런 경우를 제외하면 대부분의 경우 interface를 사용하는 것이 더 바람직합니다. 인터페이스는 추상 클래스보다 더 추상적인 존재이기 때문입니다.


해당 게시글은 프로그래머스 스쿨 강의
"실무 자바 개발을 위한 OOP와 핵심 디자인 패턴(푸)"
를 정리한 내용입니다. 쉽게 잘 설명해주시니 여러분도 강의를 듣는 것을 추천드립니다.

profile
부족함을 인정하고 노력하자

0개의 댓글