추상클래스(abstract class)
상속이 자손 클래스를 만드는데 조상 클래스를 사용하는 것이라면, 이와 반대로 추상화는 기존의 클래스의 공통부분을 뽑아내서 조상 클래스를 만드는 것.
추상화 : 클래스간의 공통점을 찾아내서 공통의 조상을 만드는 작업
구체화 : 상속을 통해 클래스를 구현, 확장하는 작업
추상클래스란?
클래스를 설계도에 비유한다면, 추상클래스는 미완성 설계도 이다.
추상클래스로 인스턴스 생성을 할 수 없고, 상속을 통해서 자손클래스에 의해서만 완성될 수 있다.
추상클래스는 자체로서는 클래스의 역할을 다 못하지만, 새로운 클래스를 작성하는데 있어서 바탕이 되는 조상클래스로서의 의미를 갖는다.
abstract class 클래스이름 {
...
}
추상메서드란?
메서드는 선언부와 구현부로 구성되어있는데,
추상메서드의 경우 선언부만 존재하고 구현부는 작성하지 않는다.
상속받는 클래스에 따라 메서드의 내용이 달라질 수 있기에 작성하지 않는것.
주석을 덧붙여 어떤 기능을 수행할 목적으로 작성되었는지 알려주고, 실제내용은 상속받는 클래스에서 구현하도록 한다.
/*주석을 통해 어떤 기능을 수행할 목적인지 간단히 알려준다 */
abstract 리턴타입 메서드이름();
추상클래스로부터 상속받는 자손클래스는 오버라이딩을 통해 조상인 추상클래스와 추상메서드를 모두 구현해주어야한다.
만약 조상으로부터 상속받은 추상메서드 중 하나라도 구현하지 않는다면, 자손클래스 역시 추상클래스로 지정해주어야한다.
abstract class Player { //추상클래스
abstract void play(int pos); //추상 메서드
abstract void stop(); //추상 메서드
}
class AudioPlayer extends Player {
void play(int pos) {/*구현부 생략*/} //추상메서드를 구현
void stop(){/*구현부 생략 */} //추상메서드를 구현
}
abstract class AbstractPlayer extends Player {
void play(int pos) {/*내용 생략*/} //추상메서드를 구현
}
기존 클래스로부터 공통된 부분을 뽑아내어 추상클래스를 만들어 보는 간단한 예제
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 load() {}
void unload() {}
}
//메소드 구현부는 생략
abstract class Unit {
int x, y;
abstract void move(int x, int y);
void stop() {}
}
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() {}
}
stop() 의 경우 모두 동일한 동작을 하지만
move() 의 경우 유닛에 따라 움직이는 방법이 서로 달라지기 때문에 최대한 공통점을 뽑아내서 추상메서드로 작성한다.
공통조상인 Unit클래스 타입의 참조변수 배열을 통해서 서로 다른 종류의 인스턴스를 하나의 묶음으로 다룰 수 있다는 것을 보여주는 예시
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);
아래의 경우 Object는 모든 클래스의 조상인 타입임에도 불구하고, move메서드가 정의 되어있지않아서 move 메서드를 호출하는 부분에서 에러가 발생한다.
Object[] 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);