**추상 클래스(Abstract Class)**는 자바에서 클래스의 공통적인 속성이나 동작을 정의하면서, 일부 메서드는 구현하지 않고 자식 클래스에서 반드시 구현하도록 강제하는 클래스입니다. 추상 클래스는 상속의 기초로 사용되며, 공통된 동작과 상태를 여러 클래스에 제공하기 위해 사용됩니다.
추상 클래스는 일반 클래스와 인터페이스의 중간 역할을 하며, 클래스 자체로는 인스턴스화할 수 없습니다. 이를 통해 특정 클래스의 기본 구조를 설계하고, 하위 클래스에서 구체적인 구현을 제공하도록 강제합니다.
1. 추상 클래스의 정의
추상 클래스는 abstract 키워드를 사용하여 선언됩니다. 추상 클래스 내에서는 추상 메서드(구현되지 않은 메서드)와 구현된 메서드 모두 정의할 수 있습니다. 추상 메서드는 구현부가 없으며, 이를 상속받는 하위 클래스가 반드시 구현해야 합니다.
예시: 추상 클래스 정의
public abstract class Animal {
// 구현된 메서드
public void eat() {
System.out.println("This animal is eating");
}
// 추상 메서드 (구현부 없음)
public abstract void sound();
}
• Animal 클래스는 추상 클래스이며, eat() 메서드는 구현되어 있지만 sound() 메서드는 추상 메서드로 선언되어 있습니다.
• sound() 메서드는 구체적인 동작이 정의되지 않았으며, 이를 상속받는 하위 클래스에서 구현해야 합니다.
2. 추상 클래스의 특징
2.1 추상 클래스는 인스턴스화할 수 없다
• 추상 클래스는 직접 인스턴스화할 수 없습니다. 즉, 추상 클래스 자체로는 객체를 만들 수 없고, 이를 상속받은 구체적인 클래스만 객체를 생성할 수 있습니다.
Animal animal = new Animal(); // 오류 발생, 추상 클래스는 인스턴스화 불가
2.2 추상 메서드와 구현된 메서드를 가질 수 있다
• 추상 클래스는 추상 메서드와 일반 메서드를 모두 포함할 수 있습니다. 추상 메서드는 구현부가 없으며, 이를 상속받는 하위 클래스가 반드시 구현해야 합니다.
public abstract class Animal {
public abstract void sound(); // 추상 메서드
public void sleep() { // 일반 메서드
System.out.println("Animal is sleeping");
}
}
2.3 상속을 통해 기능을 확장
• 추상 클래스는 상속을 통해 구체적인 클래스들이 공통적인 동작을 재사용할 수 있게 해줍니다. 자식 클래스는 추상 메서드를 반드시 구현해야 하며, 필요에 따라 부모 클래스의 메서드를 **재정의(override)**할 수 있습니다.
3. 추상 클래스의 구현
추상 클래스를 상속받는 하위 클래스는 추상 클래스의 모든 추상 메서드를 반드시 구현해야 합니다. 그렇지 않으면, 해당 하위 클래스도 추상 클래스가 됩니다.
예시: 추상 클래스 구현
// 추상 클래스
public abstract class Animal {
public abstract void sound(); // 추상 메서드
}
// 구체적인 클래스를 통해 추상 메서드 구현
public class Dog extends Animal {
@Override
public void sound() {
System.out.println("Bark");
}
}
public class Main {
public static void main(String[] args) {
Animal dog = new Dog(); // 구체적인 클래스로 인스턴스화 가능
dog.sound(); // 출력: Bark
}
}
• Dog 클래스는 Animal 추상 클래스를 상속받아 sound() 메서드를 구현합니다.
• 이제 Dog 객체를 인스턴스화할 수 있으며, sound() 메서드를 호출할 수 있습니다.
4. 추상 클래스와 인터페이스의 사용 시점
추상 클래스 사용 시점
• 상속을 통해 공통 기능을 공유하면서도 일부 메서드는 구체적인 구현이 필요할 때 사용합니다.
• 예를 들어, 모든 동물은 먹지만, 소리 내는 방식은 각기 다르기 때문에 **공통 동작(먹기)과 개별 동작(소리내기)**을 동시에 표현하고 싶을 때 추상 클래스를 사용합니다.
인터페이스 사용 시점
• 서로 다른 클래스들이 같은 행동을 강제하도록 하여 다형성을 구현하고, 여러 구현 클래스가 동일한 메서드를 제공하도록 할 때 사용합니다.
• 다중 상속을 지원하기 때문에 여러 개의 인터페이스를 구현할 수 있습니다.
5. 추상 클래스의 실제 예시
추상 클래스는 공통적인 속성과 동작을 재사용하고, 하위 클래스에서 구체적인 기능을 제공할 때 많이 사용됩니다. 예를 들어, GUI 애플리케이션에서 화면 요소(위젯)를 정의할 때 추상 클래스를 사용할 수 있습니다.
GUI 예시: 추상 클래스
// 추상 클래스: 모든 위젯의 공통적인 동작 정의
public abstract class Widget {
public abstract void draw(); // 추상 메서드
public void click() { // 일반 메서드
System.out.println("Widget clicked");
}
}
// 구체적인 클래스: 버튼 위젯
public class Button extends Widget {
@Override
public void draw() {
System.out.println("Drawing a button");
}
}
// 구체적인 클래스: 텍스트 박스 위젯
public class TextBox extends Widget {
@Override
public void draw() {
System.out.println("Drawing a text box");
}
}
public class Main {
public static void main(String[] args) {
Widget button = new Button();
button.draw(); // 출력: Drawing a button
button.click(); // 출력: Widget clicked
Widget textBox = new TextBox();
textBox.draw(); // 출력: Drawing a text box
textBox.click(); // 출력: Widget clicked
}
}
• Widget 추상 클래스는 모든 위젯이 가지고 있는 공통적인 동작인 click() 메서드를 구현하고, 각 위젯이 구체적으로 구현해야 하는 draw() 메서드는 추상 메서드로 선언했습니다.
• Button과 TextBox 클래스는 각각 위젯의 구체적인 구현을 제공하면서 draw() 메서드를 재정의했습니다.
6. 추상 클래스의 장점
1. 코드 재사용성: 추상 클래스는 공통된 동작을 여러 자식 클래스에서 재사용할 수 있습니다.
2. 일관된 설계: 추상 클래스를 사용하면 일관된 인터페이스를 제공하면서도, 각 자식 클래스에서 구체적인 구현을 달리할 수 있습니다.
3. 유연성: 상위 클래스에서 공통적인 메서드를 제공하면서, **필요에 따라 재정의(override)**할 수 있어 유연한 설계가 가능합니다.
4. 구현 강제: 추상 메서드를 통해 하위 클래스가 특정 동작을 반드시 구현하도록 강제할 수 있습니다.
7. 결론
• 추상 클래스는 구체적인 동작과 추상적인 동작을 모두 포함할 수 있으며, 상속을 통해 공통된 기능을 제공하는 데 유용합니다.
• 추상 클래스는 객체 생성이 불가능하며, 자식 클래스에서만 인스턴스화할 수 있습니다.
• 추상 클래스는 인터페이스와 달리 구현된 메서드를 가질 수 있기 때문에, 공통 동작을 포함하면서도 상속받는 클래스에 맞는 세부 동작을 강제할 수 있습니다.
• 추상 클래스와 인터페이스는 자바에서 다형성과 유연한 설계를 가능하게 하며, 상황에 맞게 선택해서 사용할 수 있습니다.
'Java' 카테고리의 다른 글
[Java] 상속 vs 합성 (0) | 2024.09.28 |
---|---|
[Java] final (0) | 2024.09.28 |
[Java] Interface (0) | 2024.09.28 |
[Java]Generic(Interface에서의 활용) (0) | 2024.09.28 |
[Java] Generic (1) | 2024.09.28 |