☕ JAVA
[Java] 추상 클래스(abstract class), 추상 메서드(abstract method)
별이⭐
2024. 5. 30. 21:46
추상 클래스(abstract class)
- 미완성 설계도
- 미완성 메서드를 가지고 있는 클래스
abstract class Player { // 추상 클래스
abstract void play(int pos); // 추상 메서드
abstract void stop(); // 추상 메서드
}
- 다른 클래스 작성에 도움을 주기 위한 것. 인스턴스 생성 불가!
- 미완성 설계도니까 제품 생성 불가!
- 상속을 통해 추상 메서드를 완성해야 인스턴스 생성이 가능하다.
class AudioPlayer extends Player {
void play(int pos) { .. } // 추상 메서드를 구현
void stop() { .. }
}
AudioPlayer ap = new AudioPlayer(); // OK
Player ap2 = new AudioPlayer(); // OK. 왜? 다형성 (조상이라 OK)
// ap2.play(); 하면 AudioPlayer 객체의 완성된 메서드가 호출된다.
// 참조 변수는 그저 기능을 사용하기 위한 리모컨 버튼만 제공한다!
추상 메서드(abstract method)
- 미완성 메서드
- 구현부({ })가 없는 메서드
- abstract를 붙이는 건 “자손이라면 ~한 기능이 있어야 해. 그니까 자손에 맞게 상속해서 구현해” 라고 강제시키는 효과이다.
- 꼭 필요하지만 자손마다 다르게 구현될 것으로 예상되는 경우에 사용한다.
abstract class Player { // 추상 클래스
abstract void play(int pos); // 추상 메서드
abstract void stop(); // 추상 메서드
}
class AudioPlayer extends Player {
// 추상 메서드를 둘 다 구현 -> 완성된 클래스
void play(int pos) { .. }
void stop() { .. }
}
abstract class AudioPlayer extends Player {
// 추상 메서드를 하나만 구현 -> 미완성 클래스
void play(int pos) { .. }
}
- 추상 메서드는 호출이 가능하다. 단 2가지 조건이 있다.
- 상속을 통해 자손을 완성하고
- 자손 객체 생성 후 호출이 가능하다.
abstract class Player {
boolean pause; // 인스턴스 변수
int currentPos;
Player() { // 생성자
pause = false;
currentPos = 0;
}
abstract void play(int pos); // 추상 메서드
abstract void stop(); // 추상 메서드
void play() { // 인스턴스 메서드
play(currentPos);
// 1. 자손이 play()를 호출
// 2. play(currentPos)가 실행
// 인스턴스 메서드는 객체 생성 후에 호출할 수 있기 때문에
// 상속을 통해 자손이 완성 -> 자손 객체 생성 후 ~.play();로 호출
}
}
추상 클래스의 작성
- 여러 클래스에 공통적으로 사용될 수 있는 추상 클래스를 바로 작성하거나 기존 클래스의 공통 부분을 뽑아서 추상 클래스를 만든다.
- 추상화된 코드는 구체화된 코드보다 유연하다 → 변경 good
abstract class Unit {
// 공통 부분 추출해서 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() {..}
}
Unit[] group = new Unit[3];
group[0] = new Marine();
group[1] = new Tank();
group[2] = new DropShip();
for (int i=0; i<group.length; i++) {
group[i].move(100, 200);
// 실제 구현된 인스턴스의 메서드가 호출된다!
}