공부 기록/Java with ChatGPT

[Java/ChatGPT] Day 11: 추상 클래스와 인터페이스(Abstrac Class & Interface)

dev.jelee 2025. 6. 19. 23:33

[ 학습목표 ]

  1. 추상 클래스와 인터페이스의 개념과 차이를 이해한다
  2. abstract 키워드를 사용한 클래스를 설계할 수 있다
  3. 인터페이스를 사용해 유연한 설계를 구현할 수 있다

[ 이론 ]

1. 추상 클래스 (abstract class)

  • 미완성 설계도 역할. 자식 클래스가 반드시 구현해야 할 메서드를 포함함

 

2. 추상 클래스 특징

  • abstract 키워드로 선언
  • 인스턴스를 만들 수 없음
  • 추상 메서드 포함 가능: abstract void methodname();
  • 일반 메서드와 필드도 포함 가능

 

3. 추상 클래스 예시

abstract class Animal {
  String name;

  void breathe() {
    System.out.println("숨을 쉽니다.");
  }

  abstract void sound();  // 자식이 반드시 구현
}

 

 

4. 인터페이스 (interface)

  • 완전히 추상적인 설계도. "무엇을 할 수 있다"라는 능력 명세

 

5. 인터페이스 특징

  • interface 키워드 사용
  • 모든 메서드는 기본적으로 public abstract
  • 다중 구현 가능 (implements)
  • 상수 (public static final)만 가질 수 있음

 

6. 인터페이스 예시

interface Flyable {
  void fly();  // public abstract 생략된 상태
}
// 다중 구현 예시
interface Flyable {
    void fly();
}

interface Swimmable {
    void swim();
}

// 클래스가 두 개의 인터페이스를 "다중 구현"함
class Duck implements Flyable, Swimmable {
    @Override
    public void fly() {
        System.out.println("날아갑니다!");
    }

    @Override
    public void swim() {
        System.out.println("헤엄칩니다!");
    }
}

 

7. 차이점 요약

항목 추상 클래스 인터페이스
상속 개수 단일 상속만 가능 다중 구현 가능
메서드 추상 + 일반 메서드 추상 메서드만 가능 (Java 8 이후 default 가능)
목적 공통 기능 제공 기능 명세 제공
생성자 가질 수 있음 가질 수 없음

[ 실습 ]

✅ 예시 1: 추상 클래스 사용

abstract class Animal {
  abstract void sound();

  void eat() {
    System.out.println("먹습니다.");
  }
}

class Dog extends Animal {
  @Override
  void sound() {
    System.out.println("멍멍!");
  }
}
public class Main {
  public static void main(String[] args) {
    Animal a = new Dog();  // 업캐스팅
    a.sound();  // 멍멍!
    a.eat();    // 먹습니다.
  }
}

 

✅ 예시 2: 인터페이스 사용

interface Flyable {
  void fly();
}

class Bird implements Flyable {
  @Override
  public void fly() {
    System.out.println("하늘을 납니다!");
  }
}
public class Main {
  public static void main(String[] args) {
    Flyable f = new Bird();  // 업캐스팅
    f.fly();  // 하늘을 납니다!
  }
}

[ 메모 ]

  • 추상 클래스는 생성할 때, 앞에 abstract를 붙인다. -> abstract class 클래스명 { ... }
  • 추상 클래스 내부에 일반 메서드와 추상 메서드, 그리고 필드를 생성할 수 있다.
  • 추상 클래스는 인스턴스(객체)를 생성할 수 없다. 그래서 상속 받는 자식 클래스를 생성해서 인스턴스를 생성해야 한다.
  • 추상 클래스 부모를 상속받는 자식은 extends 키워드 그대로 사용하면 된다.
  • 추상 클래스 부모를 상속받는 자식은 추상 메서드는 반드시 재정의(오버라이딩)을 해줘야 한다.
  • 인터페이스는 기능을 나열해놓은 명세서라고 생각하면 된다.
  • 인터페이스는 interface 키워드를 사용하여 생성한다. -> interface 이름 { ... }
  • 인터페이스 내부에 모든 메서드는 기본적으로 public abstract로 되어 있다. -> public abstract 표기를 생략 가능. 하지만 기본적으로 public abstract로 자동으로 적용되어 있음.
  • 인터페이스는 implenets 키워드를 사용하여 인터페이스를 여러 개 구현할 수 있다. (다중 구현) -> 여러 개 인터페이스를 implements(구현) 할 수 있다는 의미.
  • 인터페이스는 상수만 가질 수 있는데, public static final 로 되어 있다.
  • 상수: 변하지 않는 값 / final 키워드: 한번 초기화하면 변경 불가 / public: 어디서든 접근 가능 / static: 클래스 변수 (인스턴스 없이 접근 가능)
  • 인터페이스는 상수만 가질 수 있다고 했는데, 이는 선언만 하는 것이 아니라 반드시 초기화도 해야 한다.