동물(Animal) 과 같이 부모 클래스는 제공하지만, 실제 생성되면 안되는 클래스를 추상 클래스라 한다.
추상 클래스는 이름 그대로 추상적인 개념을 제공하는 클래스이다. 따라서 실체인 인스턴스가 존재하지 않는다. 대신에 상속을 목적으로 사용되고, 부모 클래스 역할을 담당한다.
abstract class AbastractAniaml {...}
부모 클래스를 상속 받는 자식 클래스가 반드시 오버라이딩 해야 하는 메서드를 부모 클래스에 정의할 수 있다. 이것을 추상 메서드라 한다.
추상 메서드는 이름 그대로 추상적인 개념을 제공하는 메서드이다. 따라서 실체가 존재하지 않고, 메서드 바디가 없다.
public abstract void sound();
이제 추상 클래스와 추상 메서드를 사용해서 예제를 만들어보자.
package poly.ex3;
public abstract class AbstractAnimal {
public abstract void sound();
public void move() {
System.out.println("Animal move");
}
}
이 클래스는 move() 라는 메서드를 가지고 있는데, 이 메서드는 추상 메서드가 아니다. 따라서 자식 클래스가 오버라이딩 하지 않아도 된다.
package poly.ex3;
public class Dog extends AbstractAnimal {
@Override
public void sound() {
System.out.println("멍멍");
}
}
package poly.ex3;
public class Cat extends AbstractAnimal {
@Override
public void sound() {
System.out.println("야옹");
}
}
package poly.ex3;
public class Caw extends AbstractAnimal {
@Override
public void sound() {
System.out.println("음메");
}
}
package poly.ex3;
public class AbstractMain {
public static void main(String[] args) {
// AbstractAnimal animal = new AbstractAnimal(); // 추상 클래스로 객체 생성 불가
AbstractAnimal[] animals = {new Dog(), new Cat(), new Caw()};
for (AbstractAnimal animal : animals) {
animal.sound();
animal.move();
}
}
}
멍멍
Animal move
야옹
Animal move
음메
Animal move
지금까지 설명한 제약을 제외하고 나머지는 모두 일반적인 클래스와 동일하다. 추상 클래스는 제약이 추가된 클래스일 뿐이다. 메모리 구조, 실행 결과 모두 동일하다.
추상 클래스 덕분에 실수로 Animal 인스턴스를 생성할 문제를 근본적으로 방지해준다.
추상 메서드 덕분에 새로운 동물의 자식 클래스를 만들때 실수로 sound() 오버라이딩 하지 않을 문제를 근본적으로 방지해준다.