☕ 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가지 조건이 있다.
    1. 상속을 통해 자손을 완성하고
    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);	
  // 실제 구현된 인스턴스의 메서드가 호출된다!
}