[Java/자바] 추상 클래스와 추상 메서드란 (abstract)?

추상이란 ?

추상의 사전적 의미를 보면 "여러 가지 사물이나 개념에서 공통되는 특성이나 속성 따위를 추출하여 파악하는 작용." 입니다.

"상속"이 자손 클래스를 만드는데 조상 클래스를 사용하는 것이라면,

"추상화"는 기존의 클래스의 공통적인 부분을 뽑아 조상 클래스를 만드는 것이라 할 수 있습니다.

 

추상화 : 클래스간의 공통점을 찾아 공통의 조상을 만드는 작업.
구체화 : 상속을 통해 클래스를 구현, 확장하는 작업.

 

상속계층도를 따라 내려갈수록 클래스는 점점 기능이 추가되어 구체화의 정도가 커져 세분화되고,

반대로 올라갈수록 추상화의 정도가 커져 공통요소만 남게됩니다.

 

 


추상 클래스 ( abstract class )

클래스를 설계도라 비유한다면, 추상클래스는 미완성 설계도라고 할 수 있습니다.

클래스가 미완성이란 것은, 멤버의 개수에 관계된 것이 아닌 미완성 메서드(추상 메서드)를 포함하고 있는 것입니다.

미완성 설계도로 완성된 제품을 만들 수 없듯이 추상클래스로도 인스턴스를 생성할 수 없습니다.추상 클래스는 상속을 통해서 자손클래스에 의해서만 완성될 수 있습니다.

 

추상 클래스 선언

추상 클래스의 선언은 class 앞에 "abstract"만 붙이면 됩니다.

class 앞에 "abstract"이 붙어 있다면, 이 class에는 추상메서드가 있으니 상속을 통해 구현해주어야 한다는 것을 알 수 있습니다.

abstract class 클래스이름 { ... }

 

추상 클래스는 추상 메서드를 포함하고 있다는 것을 제외하고는 일반 클래스와 다르지 않습니다.

추상 클래스에도 생성자가 있으며, 멤버변수와 메서드도 가질 수 있습니다.

 


추상 메서드 ( abstract method )

추상 메서드는 선언부만 작성하고 구현부는 작성하지 않은 채 남겨 둡니다.

즉, 설계만 해 놓고 실제 수행될 내용은 작성하지 않았기 때문에 미완성 메서드라할 수 있습니다. 

 

추상 메서드의 선언

추상 메서드 역시 "abstract"를 앞에 붙여 주면 되고, 추상메서드는 구현부가 없기 때문에 {} 중괄호 대신, 문장의 끝을 알리는 ;을 적어줍니다.

abstract 리턴타입 메서드이름(); // 주석을 통해 어떤 기능을 수행할 목적으로 작성했는지 설명

 

추상 클래스로부터 상속받는 자손클래스는 오버라이딩을 통해 조상인 추상클래스의 추상메서드를 모두 구현해야합니다.

만일 조상으로부터 상속받은 추상메서드 중 하나라도 구현하지 않는다면, 자손클래스 역시 추상클래스로 지정해 주어야합니다.

 


추상 클래스의 활용

 

추상 클래스를 활용하는 예제로 스타크래프 게임을 구현하는 것을 생각해봅시다.

이 스타크래프트 게임의 유닛들은 모두 공통적인 기능을 가지고 있습니다. 바로 "움직인다"라는 것입니다.

 

그럼 이 "움직인다"라는 move 메서드를 공통부분으로 잡고 추상 클래스인 Unit에 move 메서드를 추상메서드로 넣어줍시다.

abstract class Unit {
	int x, y;
	abstract void move(int x, int y); // 모든 유닛은 이동할 수 있어야 하므로 move 메서드를 추상메서드로 정의.
}

class Marine extends Unit {
	void move(int x, int y) { /* 지정된 위치로 이동 */ }
	void stimPack() { /* 스팀팩 사용 */ }
}

class Tank extends Unit {
	void move(int x, int y) { /* 지정된 위치로 이동 */ }
	void changeMode() { /* 시즈모드로 변환 */ }
}

class Dropship extends Unit {
	void move(int x, int y) { /* 지정된 위치로 이동 */ }
	void load() { /* 대상을 태운다. */ }
	void unload() { /* 대상을 내린다. */ }
}


public class Star {

	public static void main(String[] args) {
		Unit[] group = new Unit[4];
		group[0] = new Marine();
		group[1] = new Tank();
		group[2] = new Marine();
		group[3] = new Dropship();
		
		for (int i = 0; i < group.length; i++) {
			group[i].move(100, 200);
			
		}

	}

}

마린, 탱크, 드랍쉽들을 추상 클래스 Unit을 상속받고 상속받은 추상메서드 move를 구현합니다.

마지막으로 공통조상인 Unit클래스 타입의 참조변수 배열을 통해 서로 다른 종류의 인스턴스들을 하나의 묶음으로 다룹니다.

그리고 반복문을 통해 각 배열에 있는 인스턴스들에게 move메서드에 매개변수 값을 넣어주면 각 인스턴스들의 move 메서드가 호출됩니다.

그 이유는, 메서드는 참조변수의 타입과 관계없이 실제 인스턴스에 구현된 것이 호출되기 때문입니다.

 


참고자료 : 자바의 정석3