클래스 안에는 각자의 필드와 메소드가 존재합니다. 추상클래스는 클래스들간의 비슷한 필드와 메서드를 공통적으로 추출해 만들어진 클래스입니다.
추상클래스는 abstract 키워드를 사용하여 선언되며, 추상클래스는 추상메서드를 포함할 수 있는 클래스입니다. 추상클래스는 일반클래스와 추상메서드를 함께 포함할 수 있어, 특정한 공통 기능을 정의하면서도 서브클래스에서 구체적인 구현을 강제할 수 있습니다.
추상메서드는 메서드 본체가 없는 메서드입니다. 즉, 메서드 선언만 있고, 구현은 없기 떄문에 해당 메서드를 반드시 서브클래스에서 구현해야합니다.
공통된 필드와 메소드를 통일할 목적
실체클래스 구현시, 시간절약
규격에 맞는 실체클래스 구현
여기서 중요한 것은, 추상클래스를 상속받은 실체클래스들은 반드시 추상메서드를 재정의(오버라이딩)해서 실행내용을 작성해야 합니다.
public abstract class 클래스명{
//필드
//생성자
//메서드
//추상메서드
}
예제를 통해 알아봅시다.
Animal이라는 추상클래스를 구현했습니다. 내부를 보면, breathe()라는 일반메서드, 그리고 sound()라는 추상메서드가 존재합니다.
여기서, 추상클래스를 상속받는 실체클래스들은 반드시 sound()라는 추셍메서드를 상속받아 재정의해야합니다.
// 추상 클래스 선언
public abstract class Animal {
public String kind;
// 일반 메서드
public void breathe() {
System.out.println("This animal is breathing.");
}
// 추상 메서드 (구체적인 서브클래스에서 구현해야 함)
public abstract void sound();
}
extends키워드를 통해, Animal 추상클래스를 상속받은 실체클래스 Dog와 Cat을 구현했습니다.
// 서브클래스: Animal 클래스를 상속받아 추상 메서드를 구현
public class Dog extends Animal {
public Dog(){
this.kind = "포유류";
}
// 추상 메서드 구현
@Override
public void sound() {
System.out.println("The dog barks.");
}
}
// 서브클래스: Animal 클래스를 상속받아 추상 메서드를 구현
public class Cat extends Animal {
public Dog(){
this.kind = "포유류";
}
// 추상 메서드 구현
@Override
public void sound() {
System.out.println("The cat meows.");
}
}
추상메서드 sound()를 보면, 실체클래스에 맞게 구현되어있는것을 확인할 수 있습니다.
즉, 오버라이딩을 하면 다형성이 발생된다는 사실을 알 수 있습니다. 또한, 규격에 맞게끔 필드명과 메서드명이 통일되어있음을 알 수 있고, 실체클래스들의 코드를 보면 모양이 비슷합니다. 즉 규격이 맞춰져있음을 의미합니다.
public class AbstractClassExample {
public static void main(String[] args) {
// Animal animal = new Animal(); // 에러! 추상 클래스는 인스턴스화할 수 없음
// Dog와 Cat은 Animal을 상속받았으므로 인스턴스화 가능
Dog dog = new Dog();
Cat cat = new Cat();
dog.sound();
cat.sound();
Animal animal = null;
animal = new Dog(); //자동 타입변환
animal.sound(); //Dog에 구현된 Sound()메서드 실행
animal = new Cat(); //자동 타입변환
animal.sound(); //Cat에 구현된 Sound()메서드 실행
}
추상클래스 변수 animal에 추상클래스를 상속받아 구현한 실체클래스 인스턴스(Dog,Cat)를 주입하면, 해당 추상클래스변수는 자동 타입변환을 발생시켜 실체클래스 인스턴스처럼 사용할 수 있습니다. 이를 타입의 다형성이라고 합니다.