[인프런 Java] 추상 클래스1

코드 속의 "진돌"·2024년 3월 22일
0
post-thumbnail

✅ 추상 클래스


동물(Animal)과 같이 부모 클래스는 제공하지만, 실제 생성되면 안되는 클래스를 추상 클래스라 한다.
추상 클래스는 이름 그대로 추상적인 개념을 제공하는 클래스이다. 따라서 실체인 인스턴스가 존재하지 않는다. 대신에 상속을 목적으로 사용되고, 부모 클래스 역할을 담당한다.

abstract class AbstractAnimal {...}
  • 추상 클래스는 클래스를 선언할 때 앞에 추상이라는 의미의 **abstract 키워드**를 붙여준다.
  • 추상 클래스는 기존 클래스와 완전히 같다. 다만 new AbstractAnimal()와 같이 직접 인스턴스를 생성하지 못하는 제약이 추가된 것이다.




✅ 추상 메서드


부모 클래스를 상속 받는 자식 클래스가 반드시 오버라이딩 해야 하는 메서드를 부모 클래스에 정의할 수 있다. 이것을 추상 메서드라 한다.
추상 메서드는 이름 그대로 추상적인 개념을 제공하는 메서드이다. 따라서 실체가 존재하지 않고, 메서드 바디가 없다.

public abstract void sound();
  • 추상 메서드는 선언할 때 메서드 앞에 추상이라는 의미의 abstract 키워드를 붙여주면 된다.
  • 추상 메서드가 하나라도 있는 클래스는 추상 클래스로 선언해야 한다.
    • 그렇지 않으면 컴파일 오류가 발생한다.
    • 추상 메서드는 메서드 바디가 없다. 따라서 작동하지 않는 메서드를 가진 불완전한 클래스로 볼 수 있다. 따라서 직접 생성하지 못하도록 추상 클래스로 선언해야 한다.
  • 추상 메서드는 상속 받는 자식 클래스가 반드시 오버라이딩 해서 사용해야 한다.
    • 그렇지 않으면 컴파일 오류가 발생한다.
    • 추상 메서드는 자식 클래스가 반드시 오버라이딩 해야 하기 때문에 메서드 바디 부분이 없다. 바디 부분을 만들면 컴파일 오류가 발생한다.
    • 오버라이딩 하지 않으면 자식도 추상 클래스가 되어야 한다.
  • 추상 메서드는 기존 메서드와 완전히 같다. 다만 메서드 바디가 없고, 자식 클래스가 해당 메서드를 반드시 오버라이딩 해야 한다는 제약이 추가된 것이다.




✅ 예제3


✏️ AbstractAnimal

package poly.ex3;

public abstract class AbstractAnimal {

  public abstract void sound();

  public void move() {
    System.out.println("동물이 움직입니다.");
  }
}
  • AbstractAnimalabstract가 붙은 추상 클래스이다. 이 클래스는 직접 인스턴스를 생성할 수 없다.
  • sound()abstract가 붙은 추상 메서드이다. 이 메서드는 자식이 반드시 오버라이딩 해야 한다.

이 클래스는 move()라는 메서드를 가지고 있는데, 이 메서드는 추상 메서드가 아니다. 따라서 자식 클래스가 오버라이딩 하지 않아도 된다.



✏️ Dog

package poly.ex3;

public class Dog extends AbstractAnimal {

  @Override
  public void sound() {
    System.out.println("멍멍");
  }
}



✏️ Cat

package poly.ex3;

public class Cat extends AbstractAnimal {
  
  @Override
  public void sound() {
    System.out.println("냐옹");
  }
}



✏️ Caw

package poly.ex3;

public class Caw extends AbstractAnimal {

  @Override
  public void sound() {
    System.out.println("음매");
  }
}



✏️ AbstractMain

package poly.ex3;

public class AbstractMain {

  public static void main(String[] args) {
    // 추상 클래스 생성 불가
    //AbstractAnimal animal = new AbstractAnimal();

    Dog dog = new Dog();
    Cat cat = new Cat();
    Caw caw = new Caw();

    cat.sound();;
    cat.move();

    soundAnimal(dog);
    soundAnimal(cat);
    soundAnimal(caw);
  }

  // 동물이 추가되어도 변하지 않는 코드
  private static void soundAnimal(AbstractAnimal animal) {
    System.out.println("동물 소리 테스트 시작");
    animal.sound();
    System.out.println("동물 소리 테스트 종료");
  }
}



🖥️ 실행 결과



⚙️ 오류 설명

1️⃣ 추상 클래스는 생성이 불가능하다.

다음 코드의 주석을 풀고 실행하면 컴파일 오류가 발생한다.

// 추상 클래스 생성 불가
AbstractAnimal animal = new AbstractAnimal();

✓ 컴파일 오류 - 인스턴스 생성

java: poly.ex3.AbstractAnimal is abstract; cannot be instantiated

AbstractAnimal가 추상이어서 인스턴스 생성이 불가능하다는 뜻이다.


2️⃣ 추상 메서드는 반드시 오버라이딩 해야 한다.

만약 자식에서 오버라이딩 메서드를 만들지 않으면 다음과 같이 컴파일 오류가 발생한다.

package poly.ex3;

public class Dog extends AbstractAnimal {

/*
  @Override
  public void sound() {
    System.out.println("멍멍");
  }
*/
}

✓ 컴파일 오류 - 오버라이딩X

java: poly.ex3.Dog is not abstract and does not override abstract method 
sound() in poly.ex3.AbstractAnimal

Dog는 추상클래스가 아닌데 sound()가 오버라이딩 되지 않았다는 뜻이다.



📚 정리

지금까지 설명한 제약을 제외하고 나머지는 모두 일반적인 클래스와 동일하다. 추상 클래스는 제약이 추가된 클래스일 뿐이다. 메모리 구조, 실행 결과 모두 동일하다.

  • 추상 클래스 덕분에 실수로 Animal 인스턴스를 생성할 문제를 근본적으로 방지해준다.
  • 추상 메서드 덕분에 새로운 동물의 자식 클래스를 만들때 실수로 sound()를 오버라이딩 하지 않을 문제를 근본적으로 방지해준다.

출처 : 김영한의 실전 자바 - 기본편
https://www.inflearn.com/course/김영한의-실전-자바-기본편/dashboard

profile
매일 성장하는 주니어 개발자의 기록📝

0개의 댓글