Java - Abstract Class vs Interface


1. 추상클래스(Abstract Class) vs 인터페이스(Interface)

1.1. 추상클래스

  • 호랑이는 동물이다. ( class Tiger extends Animal 의 느낌이다. )


사용 이유

  • 자식 클래스들이 추상메서드를 반드시 구현하도록 강요하기 위해서 만듦.
  • 공통되는 변수나 메서드를 하나로 묶어 유지보수성이 좋아짐.
  • 서로 관련이 있는 클래스를 논리적으로 묶기 위해 사용.
  • DIP와 OCP를 지키며 설계하기에 좋음.
  • 개발 시간 단축과 협업을 위해 사용하기도 함. ( 프론트 개발자들은 빨리 API를 받아야되는데 백 개발자들이 바쁠 경우, 가라 데이터와 리턴 형식이라도 먼저 받기 위해 사용하기도 한다. )


특징

  • abstract 키워드 사용
  • 사용가능 변수타입 제한 x
  • 사용가능 접근제어자 제한 x
  • 사용가능 메서드 제한 x
  • extends 상속 키워드 사용
  • 다중 상속 x


단점

  • 너무 많은 자식 클래스가 있을 경우, 추상 클래스에 추상 메서드를 추가하면, 수 많은 자식 클래스들에서도 추상 메서드를 확장해주어야 함. ( 심지어 사용하지 않는 메서드일지라도 추상메서드이므로 확장해주어야 되는 문제 발생 )


1.2. 인터페이스

  • “나”라는 구현체가 안경이라는 인터페이스, 헬스라는 인터페이스, 개발자라는 인터페이스를 implement 하여 구현되고 있다. 이건 ISP.. 인터페이스 분리 원칙을 떠올릴 수 있게 하는 중요한 표현이다. ( class Me implements Glasses, Health, Developer )


사용 이유

  • 설계도로 사용한다.
  • 개발 시간 단축과 협업을 위해 사용한다. ( 같은 인터페이스를 공유하는 다른 구현체를 개발하는 사람과 동시에 개발을 진행하기 위해 먼저 틀을 만들어 두는 개념 )
  • 추상클래스와는 다르게, 서로 논리적으로 관련성이 없는 클래스를 묶어 주고 싶을 때에도 사용한다.
  • 즉, 자유로운 타입의 묶음이다.


특징

  • interface 키워드 사용
  • 사용가능 변수타입은 static final 상수만 가능
  • 사용가능 접근 제어자는 public 만 가능
  • 사용가능 메서드는 abstract, default, static, private 만 가능
  • implements 상속 키워드 사용
  • 다중 상속 o


인터페이스의 default 메서드와, static 메서드란?

  • 일단 메서드도 함께 만들 수 있는 추상클래스와는 다르게, 인터페이스는 무조건 추상메서드만 만들 수 있었다. 그러나 다중상속이 가능한 인터페이스의 특성상 제약이 너무 강한 탓에 유연성이 떨어지게 되었다, 그래서 Java 8부터는 default 메서드와 static 메서드를 지원해준다.
  • default 메서드는 implements한 구현 클래스에서 굳이 확장을 하지 않아도 사용할 수 있는 메서드이다.
  • static method는 implements 하지 않아도 그냥 인터페이스에서 호출이 가능한 메서드이다.
      // default method 예시
      interface MyInterface {
          default void myDefaultMethod() {
              System.out.println("Default 메서드");
          }
    
          void myAbstractMethod();
      }
    
      class MyClass implements MyInterface {
          @Override
          public void myAbstractMethod() {
              System.out.println("구현된 추상 메서드");
          }
      }
    
      public class Main {
          public static void main(String[] args) {
              MyInterface obj = new MyClass();
              obj.myDefaultMethod(); // Default 메서드 호출
              obj.myAbstractMethod(); // 구현된 추상 메서드 호출
          }
      }
    
      // static method 예시
      interface MyInterface {
          static void myStaticMethod() {
              System.out.println("Static 메서드");
          }
    
          void myAbstractMethod();
      }
    
      public class Main {
          public static void main(String[] args) {
              MyInterface.myStaticMethod(); // Static 메서드 호출
          }
      }
    


추상클래스와 인터페이스의 공통점

  • 추상 메서드를 가지고 있어야 한다.
  • 인스턴스화가 불가능 하다. ( new 가 안된다는 이야기 )
  • 상속 받아 사용하는 구현체의 인스턴스를 이용해야 한다.
  • 상속,구현클래스들은 반드시 추상 메서드를 구현해줘야 한다.



2. 다중 상속이란?

  • 하나의 자식이 여러개의 부모를 갖는 것이다.
  • 클래스를 대상으로는 불가능하며, 인터페이스를 대상으로만 가능하다.
      public class Son extends FatherA, FatherB {
          // Error
      }
    	
      public class People extends Animal implements Talkable, Swimmable {
          // 가능
      }
    
      public class A implements B, C, D, E {
          // 가능
      }
    


  • 클래스에서는 다중 상속이 안되는 이유가 다이아몬드 문제 때문이다.
      class GrandFather {
          void myMethod(){
              System.out.println("GrandFather");
          }
      }
    
      class FatherA extends GrandFather {
          @Override
          void myMethod(){
              System.out.println("FatherA");
          }
      }
    
      class FatherB extends GrandFather {
          @Override
          void myMethod(){
              System.out.println("FatherB");
          }
      }
    
      class Son extends FatherA, FatherB{
          @Override
          void myMethod() {
              super.myMethod(); //FatherA를 출력해야 할까? FatherB를 출력해야 할까?
          }
      }
    


  • 참고로 인터페이스도 default method를 사용하면 동일한 문제가 생기지 않느냐? 라고 할 수 있는데 implement 클래스는 를 interface의 default method를 super로 접근하려면 앞에 어떤 인터페이스인지를 명시해주어야 하므로 상관없다.
      class MyClass implements InterfaceA, InterfaceB {
          @Override
          public void myDefaultMethod() {
              InterfaceA.super.myDefaultMethod();
          }
      }
    






results matching ""

    No results matching ""