본문 바로가기

프로그래밍 언어 기초/JAVA

Chapter 10. 추상클래스(Abstract class)

10. 1. 추상클래스(Abstract class)란?

 자바에서 일반 클래스는 필드와 메소드 구성되어 있습니다. 그런데 지난 챕터에서 언급한 객체지향 프로그래밍에 대해서 잠시 생각을 해보자면, 반복된 코드를 줄이고 기존에 작성된 코드를 재활용해서 사용할 수 있는 방법으로 상속(Inheritance)이 있었습니다. 그런데, 상속의 단점은 부모 클래스에서 작성한 그대로 사용해야 한다는 것입니다. 그렇다면, 방법은 한가지, 메소드를 재정의 하는 오버라이딩(Overriding)을 사용하면 되지 않을까요?

 

그런데, Overriding을 그대로 사용하기에는 귀찮은 점이 하나가 아닙니다. 어노테이션이 있다고 하더라도, 접근 제한자도 알아야 하고 리턴타입은 뭔지 함수명은 뭐였는지 일일이 찾는다면 얼마나 번거로울까요? 그래서 훌륭하신 자바 개발진들은 추상 클래스(abstract class)라는 것을 만들게 되었습니다. 원래 메소드란 접근 제한자로 시작하는 함수의 선언부와 {}로 구분되는 내부 로직이 그 구성성분인데요. 기존에는 일반 클래스에서 {} 에 구현했던 코드들을 {}와 함께 모두 지워버리고 abstract라는 키워드를 붙여주어 다른 메소드와 확실하게 구분 했습니다.

 

 그렇다면 왜 확실히 구분했을까요? 바로 추상 클래스 내부에는 추상 메소드가 아닌 일반 메소드도 섞어서 사용할 수 있기 때문입니다. 따라서 이를 명확히 구분하기 위해 추상 메소드에는 반드시 접근 제한자 뒤에 abstract라는 키워드를 붙여주어야 하고, 원래라면 로직이 작성되었을 바디 부분 ({})을 모두 지운 형태로 작성하면 됩니다.

 

// 추상 메소드가 하나라도 있다면, abstract 키워드를 붙여야 한다!
public abstract class AbstractClass { 
	
	int value;
	
	public void call() { // 일반 메소드!
		System.out.println("Hello "+this.getClass().getName()+" ~!");		
	}
	
	public abstract void print(); // 접근제한자와 리턴타입 함수명 등 선언부만 존재하고 
    							  // 바디(body, {})는 없는 형태!

}

 

이렇게 작성하는 코드 작성 스타일을 Abstract Method Design Pattern 이라고 한답니다.

 

 추상 클래스나 추상 메소드에는 접근 제한자(Access Modifier) private를 사용할 수 없습니다. 그 이유는 추상 클래스나 메소드의 특징을 생각해보면 유추할 수 있는데요. body가 없이 선언부만 있는 추상 클래스는 반드시 다른 곳에서 오버라이딩되어야 합니다. 그런데 private 접근 제한자로 한다면 패키지가 같아도 상속을 받아도 새롭게 작성할 수 없겠죠? 그래서 추상 클래스나 추상 메소드에는 private 접근 제한자를 붙일 수 없으며, 컴파일 오류가 발생하게 됩니다.

 

abstract class OtherAbsClass{ 
	// 추상메서드만 있는 형태도 가능!
	public abstract void print();
	abstract void call();
	protected abstract void say();
		
	// abstract는 private 접근 제한자는 사용할 수 없다
	// why? private 로 하면 구현을 상속해서도 구현하지 못하는 모순적인 상황이 발생하므로 컴파일 오류가 발생	
	
}