Langauge/Java-basic

[Java] 추상 클래스와 추상 메소드 (abstract 제어자)

강잇 2022. 8. 5. 21:16

abstarct 제어자

abstract란?

  • abstract의 '추상적인'의 사전적 의미를 가지며, 자바의 맥락에서는 '미완성'을 의미한다.
  • 추상 클래스 또는 추상 메서드를 정의할 때 사용한다.
  • abstract + class : 추상 클래스
  • abstract + method : 추상 메서드

추상 메서드

추상 메서드란?

  • 추상 메서드란 기능이 정해지지 않은 미완성 메서드를 의미한다.
  • 미완성이라는 의미는 메서드 내부에 기능이 구현되어 있지 않은 상태를 의미한다.

추상 메서드 구조

  • 다음 코드를 보면 메서드 내부의 기능은 물론 중괄호({})조차 없다.
  • 기능 자체가 없는 미완성 메서드로 완성 전까지는 사용할 수 없다.
  • 완성은 하위 클래스에서 메서드 오버라이딩을 통해 완성시킬 수 있다.
범위 제어자 abstract 리턴 타입 메서드명();

// 예시
public abstarct void cry();

추상 메서드 사용 이유

  • 메서드 오버라이딩용으로 메서드를 정의할 때 효율적
    -> 하위 클래스의 공통적인 기능을 상위 클래스 한 곳에 정의할 때 아무런 기능을 하지 않아 중괄호 안을 비워둘 때는 중괄호 자체가 없는 추상 메서드로 정의하는 것이 효율적이다.
class Animal {
    // 메서드 오버라이딩용 - 일반 메서드
    // 어떠한 기능을 하는지 한 번에 알 수 없다.
    void sound() {}
}

abstract class Animal {
    // 메서드 오버라이딩용 - 추상 메서드
    // 어떠한 기능을 하는지 추상 메서드 구조를 보고 알 수 있다.
    abstract void sound();
}
  • 오버라이딩할 때 에러 방지
    -> 예를 들어 sound()라는 메서드를 오버라이딩할 때 오타가 발생하여 soudn()로 선언하였다.
    이 경우 메서드가 2개 선언된 것으로 에러가 발생하지는 않지만 다형성으로 상위 클래스의 타입으로 객체를 생성하여 sound()라는 메서드를 호출하면 예상외의 결과가 발생한다. 
public class Main {
    public static void main(String[] args) throws IOException {
        // 상위 클래스 타입으로 각각 객체 생성
        Animal dog = new Dog();
        Animal cat = new Cat();
        // sound() 메서드 호출
        dog.sound();
        cat.sound();
    }

}
class Animal {
    void sound(){}; 구현을 하위 클래스로 넘김
}
class Dog extends Animal {
    void soudn() { // 오타 발생
        System.out.println("멍멍");
    }
}
class Cat extends Animal {
    void sound() { // 오버라이딩
        System.out.println("냐옹");
    }
}

오타로 인해 예상 외의 결과 출력

  • 하위 클래스에 재 구현 강요
    -> 추상 메서드가 아닌 일반 메서드로 정의하여 하위 클래스에게 구현을 넘긴다고 가정해보자.
    이때 하위 클래스에서 해당 메서드의 구현(오버라이딩)을 하지 않는 경우가 발생할 수 있다.
    이것을 방지하고자 추상 메서드로 정의하여 상속 받는 하위 클래스에게 반드시 재 구현하도록 강요할 수 있다.  

구현 강요

추상 클래스

추상 클래스란?

내부에 추상 메서드를 1개 이상 포함할 경우 반드시 추상 클래스로 정의해야 한다.

추상 클래스는 말 그대로 추상적인 클래스로, 추상 클래스만으로는 객체를 생성할 수 없다.

추상 클래스 정의

class 앞에 abstract 제어자를 붙여 추상 클래스로 선언할 수 있다.

abstract class 클래스명 {
}

// 예시
abstract class AbstractClass {
}

추상 클래스 타입의 객체 생성

하위 클래스를 이용한 방법

abstract class AbstractClass {
    abstarct void print();
}

class MyClass extends AbstarctClass {
    void print() { // 추상 메서드 구현
        System.out.println("MyClass - 출력");
    }
}
// 하위 클래스를 정의해 추상 클래스 타입으로 객체 생성
AbstractClass myClass = new MyClass();

익명 이너 클래스를 이용해 객체 생성

abstract AbstractClass {
    abstract void print();
}
// 익명 이너 클래스를 이용하여 추상 클래스 타입의 객체 생성
AbstractClass abstractClass = new AbstractClass() {
    void print() { // 추상 메서드 구현
        System.out.println("출력");
    }
};

추상 클래스의 장점

  • 추상 클래스를 상속받은 하위 클래스에서 추상 메서드를 반드시 구현하도록 강요한다.
    -> '추상 클래스를 상속한 모든 하위 클래스 내부에는 추상 메서드가 재 구현되어 있다'는 것이 보장된다.
  • 공통적인 속성과 기능을 추출하여 한 곳에서 관리하기 때문에 추상화를 구현하는데 핵심적인 역할을 한다.
  • 상속 관계에 있어 새로운 클래스를 작성하는데 유용하다.
    -> 하위 클래스에서 오버라이딩을 통해 각각 상황에 맞는 메서드 구현이 가능하다.