본문 바로가기
자바

추상클래스와 인터페이스

by 이상한나라의개발자 2023. 12. 11.

추상 클래스 : 인스턴스화할 수 없는 클래스입니다. 즉, 객체로 만들 수 없습니다. ( 추상메서드를 익명으로 구현하면 가능하지만요..) 이 클래스는 다른 클래스가 상속 받아 사용될 목적으로 설계 됩니다.

 

  • 부모 클래스는 제공하지만 실제 인스턴스가 생성 되면 안되는 클래스
  • 추상클래스는 말 그대로 추상적인 개념만 제공하는 클래스로 사용되어야 한다.
  • 상속을 목적으로 사용된다.
// 추상 클래스로 선언
public abstract class Animal {
    public void sound() {
        System.out.println("Animal.sound()");
    }
}


public class AnimalSoundMain {
    public static void main(String[] args) {
        Dog dog = new Dog();
        Cat cat = new Cat();
        // 추상 클래스는 추상적인 개념만 제공하므로 실제 인스턴스화가 되면 안된다.
        Animal animal = new Animal();

        sound(dog);
        sound(cat);
    }

    private static void sound(Animal animal) {
        animal.sound();
    }
}

 

 

추상 메소드 : 추상 클래스는 추상 메소드를 포함할 수 있습니다. 추상 메소드는 본체(body)가 없는 메소드로, 구현되지 않은 메소드 입니다. 자식 클래스에서는 추상 메소드를 반드시 오버라이딩 (재정의) 하여 구현해야 합니다.

 

  • 부모 클래스를 상속 받은 자식 클래스가 반드시 오버라이딩 해야하는 메서드를 부모 클래스에서 정의할 수 있다.
  • 추상 메서드는 말 그대로 추상적인 개념을 제공하는 메서드이므로 바디를 제공하지는 않는다.
  • 추상 메서드가 하나라도 있는 클래스는 추상 클래스로 만들어야 한다.

 

추상메소드를 잘 사용하면 중복되는 코드를 줄일 수 있습니다 ( 템플릿 메소드 패턴 참조 )

 

public abstract class AbstractClass {

    public void implementedMethod() {
        System.out.println("implemented method");
        abstractMethod();
    }
    abstract public void abstractMethod();
}



public class ExtendedAbstractClass extends AbstractClass {
    @Override
    public void abstractMethod() {
        System.out.println("abstract method");
    }
}


public class AbstractMain {

    public static void main(String[] args) {
        // AbstractClass abstractClass = new AbstractClass(); // 추상 클래스는 인스턴스화 할 수 없음
        // 추상 클래스는 인스턴스할 수 없지만 , 추상 메서드를 구현함으로써 가능하게할 수 있음.
        AbstractClass abstractClass = new AbstractClass() {
            @Override
            public void abstractMethod() {
                System.out.println("abstractClass abstractMethod");
            }
        };

        abstractClass.abstractMethod();
        abstractClass.implementedMethod();

        AbstractClass extendedAbstractClass = new ExtendedAbstractClass();
        extendedAbstractClass.implementedMethod();
        extendedAbstractClass.abstractMethod();
    }
}

 

인터페이스 (Interface)

 

인터페이스는 모든 멤버 변수가 "public static final (상수)" 이며, 모든 메소드가 "public abstract" 로 정의된 추상 타입입니다. 다시 말해, 인터페이스는 구체적인 구현을 포함하지 않는 메소드 선언들의 집합입니다. 상수는 관례상 대문자+_(언더스코어) 로 표현됩니다.

 

다중상속 : 자바에서 클래스의 다중상속을 허용하지 않습니다. 하지만 한 클래스는 여러 인터페이스를 동시에 구현할 수 있습니다. 이는 다중상속의 문제를 피하면서 여러 형태의 상속을 가능하게 합니다.

 

디폴트 메소드와 정적 메소드 : Java8 부터는 디폴트 메소드와 정적 메소드를 구현할 수 있습니다. 정적 메소드는 인터페이스 이름으로 호출하게 됩니다.

 

장점 : 여러 클래스에 걸쳐 공통적으로 사용되는 메소드의 명세(스펙)을 정의할 때 사용 함으로써, 클래스는 인터페이스를 통해 정의된 규약을 준수하게 됩니다. 이렇게 함으로써 다양한 객체가 동일한 방식으로 동작하는 것을 보장할 수 있습니다.

 

 

public interface SomeInterface {

    public static final String ANIMAL_NAME = "cat";

    void someMethod();

    default void defaultMethod() {
        System.out.println("default method");
    }
}

public interface AnotherInterface {
    void anotherMethod();
}

public class ImplementsClass implements SomeInterface, AnotherInterface {
    @Override
    public void someMethod() {
        System.out.println(ANIMAL_NAME  + "some method");
    }
    @Override
    public void anotherMethod() {
        System.out.println(ANIMAL_NAME + "another method");
    }
}

 

 

이런 질문이 나올 수 있는데요, 인터페이스에 default 메소드와 static 메소드를 구현할 수 있다면 abstract 클래스와 차이가 없다고 말이죠. 하지만 문법적이나 용도면에서 다른 측면을 보이는데요. 아래와 같은 내용이 아니라면 보통 interface를 사용하는 것을 추천 드립니다.

 

1. 인스턴스 변수(필드) 가 필요한 경우

2. 생성자가 필요한 경우 

3. Object 클래스의 메소드 오버라이딩 하고 싶은경우

4. 모든 메서드가 추상으로 구현해야 되는 경우

5. 제약 : 인터페이스를 만드는 이유는 인터페이스를 구현하는 곳에서 인터페이스의 메서드를 반드시 구현혀라는 규약(제약)을 주는 것이다. USB 인터페이스를 생각해보자. USB 인터페이스에 맞추어 키보드, 마우스를 개발하고 연결해야 한다. 그렇지 않으면 작동하지 않는다. 인터페이스의 규약{(제약)은 반드시 구현해야 하는 것이다. 그런데 순수 추상 클래스의 경우 미래에 누군가 그곳에 실행 가능한 메서드를 끼워 넣을 수 있다. 이렇게 되면 추가된 기능을 자식 클래스에서 구현하지 않을수도 있고, 또 더는 순순 추상 클래스가 아니게 된다. 인터페이스는 모든 메서드가 추상 메서드이다. 따라서 이런 문제를 원천 차단할 수 있다.

6. 다중구현 : 자바에서 클래스는 상속을 부모를 하나만 지정할 수 있다. 반면에 인터페이스는 부모를 여러명 두는 다중 구현(다중 상속)이 가능하다.

 

자바8에 등장한 default 메서르를 사용하면 인터페이스도 메서드를 구현할 수 있다. 하지만 이것은 예외적으로 아주 특별한

'자바' 카테고리의 다른 글

예외  (0) 2023.12.11
캡슐화  (0) 2023.12.11
상속과 다형성 기본  (0) 2023.12.11
객체지향적으로 개발해야 하는 이유  (0) 2023.12.11
동시성 이슈  (2) 2023.12.11