[Java]추상클래스

황세호·2021년 5월 16일
0

Java

목록 보기
3/6

추상 클래스(abstract class)


추상클래스란?

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

추상클래스는 키워드 abstract를 붙이기만 하면 된다. 이렇게 함으로써 이 클래스를 사용할 때, 클래스 선언부의 abstract를 보고 이 클래스에는 추상메서드가 있으니 상속을 통해서 구현해주어야 한다는 것을 쉽게 알 수 있다.

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

추상클래스는 추상메서드를 포함하고 있다는 것을 제외하고는 일반클래스와 전혀 다르지 않다. 추상클래스에도 생성자가 있으며, 멤버변수와 메서드도 가질 수 있다.

추상클래스를 사용하는 이유

같은 크기의 TV라도 기능의 차이에 따라 여러 종류의 모델이 있지만, 이 들 설계도는 아마 90% 정도는 동일할 것이다. 서로 다른 세 개의 설계도를 따로 그리는 것보다는 공통적인 부분을 그리는 미완성 설계도를 만들어 놓고, 이 미완성 설계도를 이용해서 각각의 설계도를 완성하는 것이 훨씬 효율적이다.

상속 vs 추상화

상속

  • 자손 클래스를 만드는데 조상 클래스를 사용
  • 상속계층도를 따라 내려갈수록 클래스는 점점 기능이 추가되어 구체화가 심화됨

추상황

  • 기존의 클래스의 공통부분을 뽑아내서 조상 클래스를 만듬
  • 상속계층도를 올라갈수록 클래스는 추상화의 정도가 심해짐 (공통요소만 남게 됨)

추상메서드(abstract method)


메서드는 선언부구현부로 구성되어 있다고 했다. 선언부만 작성하고 구현부는 작성하지 않은 채로 남겨 둔 것이 추상메서드이다. (설계만 해놓고 실제 수행될 내용은 작성하지 않았기에 미완성 메서드인 것)

/* 메서드의 기능 목적 */
abstract 리턴타입 메서드이름();
  • 선언부만을 작성하고, 주석을 덧붙여 어떤 기능을 수행할 목적인지 알려준다.
  • 추상클래스로부터 상속받는 자손클래스는 오버라이딩을 통해 조상인 추상클래스의 추상메서드를 모두 구현해주어야 한다.

실제 작업내용인 구현부가 없는 메서드가 무슨 의미가 있을까 싶겠지만, 메서드를 작성할 때 구현부보다 더 중요한 부분이 선언부이다.
메서드의 이름, 매개변수, 반환 타입을 결정하는 것은 쉬운 일이 아니기 때문이다.

추상클래스의 작성


우선, 여러 클래스에 공통적으로 사용될 수 있는 클래스를 바로 작성해보도록 하자
아래는 Player라는 추상클래스이다. ( 이 클래스는 VCR이나 Audio와 같은 재생 기기를 클래스로 작성할 때, 이들의 조상으로 사용될 수 있다.)

abstract class Player {
	boolean pause;     // 일시정지 상태를 저장하기 위한 변수
	int currentPos;    // 현재 play되고 있는 위치를 저장하기 위한 변수

	Player() {         // 추상클래스도 생성자가 있어야 함
		pause = false;
		currentPos = 0;
	}

	abstract void play(int pos);     // 추상메서드

	abstract void stop();            // 추상메서드

	void play() {
		play(currentPos);
	}

	void pause() {
		if(pause) {
			pause = false;
			play(currentPos);
		} else {
			pause = true;
			stop();
		}
	}
}

이제 Player클래스를 조상으로 하는 MP3Player 클래스를 만들어 보자.

class MP3Player extends Player {
	void play(int currentPos) {
		/* 조상의 추상메서드를 구현 */
	}
	
	void stop() {
		/* 조상의 추상메서드를 구현 */
	}

	int currentAlbum;     // 현재 재생중인 앨범

	void nextAlbum() {
		...
	}
	void preAlbum() {
		...
	}
}

이번에는, 기존의 클래스로부터 공통된 부분을 뽑아내어 추상클래스를 만들어 보도록 하자.

class Marine {
	int x,y;
	void move(int x, int y) {}
	void stop() {}
	void stimPack() {}
}

class Tank {
	int x,y;
	void move(int x, int y) {}
	void stop() {}
	void changeMode() {}
}

class Dropship {
	int x,y;
	void move(int x, int y) {}
	void stop() {}
	void unload() {}
}

위의 클래스들로부터 공통 부분을 뽑아내어 하나의 클래스로 만들고, 이를 상속받는 구조를 코드로 작성해보자.

abstract class Unit {
	int x,y;
	abstract void move(int x, int y);
	void stop();
}

/* 각 유닉마다 이동 방식이 다르므로 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 unload() {}
}
profile
Developer

0개의 댓글