📔 본 포스팅은 자바의 정석(남궁성 저, 3판)을 읽고 정리한 내용입니다.
abstract class Player{ // 추상클래스 (미완성 클래스)
abstract void play(int pos); // 추상 메서드 (몸통 {}이 없는 메서드)
abstract void stop(); // 추상 메서드
void move() { /* 생략 */ }
}
Player p = new Player(); // 에러. 추상 클래스의 인스턴스 생성 불가
class AudioPlayer extends Player{ // 추상 클래스 Player의 추상 메서드 2개를 모두 구현
void play(int pos) { // 추상 메서드를 구현(완성)
/* 내용생략 */
}
void stop() { // 추상 메서드를 구현(완성)
/* 내용 생략 */
}
}
// 완성한 클래스는 인스턴스 생성 가능
AudioPlayer ap1 = new AudioPlayer(); // OK
Player ap2 = new Player(); // OK. 다형성의 정의. 참조변수는 리모컨만 제공
/* 주석을 통해 어떤 기능을 수행할 목적으로 작성하였는지 설명한다. */
abstract 리턴타입 메서드이름();
abstract
를 붙인다abstract class Player{ // 추상클래스 (미완성 클래ㅡㅅ)
abstract void play(int pos); // 추상 메서드 (몸통 {}이 없는 메서드)
abstract void stop(); // 추상 메서드
}
// 추상 클래스 Player의 추상 메서드 2개를 모두 구현
class AudioPlayer extends Player{
void play(int pos) { // 추상 메서드를 구현(완성)
/* 내용생략 */
}
void stop() { // 추상 메서드를 구현(완성)
/* 내용 생략 */
}
}
// 추상 클래스 Player의 추상 메서드 중 1개만 구현
abstract class AbstractPlayer extends Player {
void play(int pos) { // 추상 메서드를 구현(완성)
/* 내용생략 */
}
// 사실은 상속받은 추상메서드 stop()이 있음
}
abstract
를 붙여줘야한다.abstract
를 붙여 클래스 내부에 구현하지 않은 추상 메서드가 있음을 알린다abstract
를 붙임으로써, 자식 클래스는 이 추상 메서드를 반드시 구현해야하는 강제성을 갖게 된다.abstract class Player {
boolean pause;
int currentPos;
Player() {
pause = false;
currentPos = 0;
}
/** 지정된 위치(pos)에서 재생을 시작하는 기능이 수행되도록 작성되어야 한다.*/
abstract void play(int pos); // 추상 메서드
/** 재생을 즉시 멈추는 기능이 수행되도록 작성되어야 함*/
abstract void pause(); // 추상 메서드
void play() {
play(currentPos); // 추상메서드를 사용할 수 있다.
}
}
abstract class Unit {
int x, y;
abstract void move(int x, int y); // 리모컨의 버튼으로 사용
void stop() {/* 현재 위치에 정지*/}
}
class Marine extends Unit {
@Override
void move(int x, int y) { /* 지정된 위치로 이동 */ }
void stimPack() {}
}
class Tank extends Unit {
@Override
void move(int x, int y) {}
void changeMode() {}
}
class Dropship extends Unit {
@Override
void move(int x, int y) {}
}
Unit[] group = new Unit[3]; // gruop의 타입은 Unit[], Unit[]은 객체배열.
group[0] = new Marine();
group[1] = new Tank();
group[2] = new Dropship();
for(int i = 0; i< group.length; i++){
// group[i]는 Unit타입임
group[i].move(100, 200); // Unit 리모컨의 move() 버튼 사용
}
// 위의 코드와 비교
Object[] 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); // 에러. Object 리모컨에는 move()버튼이 없음
}
(참고) 객체 배열 : 참조변수 묶은 것
// 1. 내가 GregorianCalendar 객체를 사용할 것이 분명함 -> 구체적
GregorianCalendar cal = new GregorianCalendar(); // 구체적
// 2. getInstance메서드가 정확하게 '무슨' 객체를 반환할지 모름 -> 불명확. 추상적
Calendar cal = Calendar.getInstance(); // Calendar의 자손 객체를 반환. 추상적
추상 클래스는 기능이 비슷한 클래스들을 한 데 묶는 조상 역할을 한다
abstract
로 선언된 추상 메서드를 하위 클래스에서 반드시 오버라이딩함public abstract class Animal {
public abstract void eat();
public void move() {
System.out.println("무리를 지어서 이동한다.");
}
}
public class Dog extends Animal {
public void eat() {
System.out.println("개처럼 먹다");
}
}
public class Cat extends Animal {
public void eat() {
System.out.println("고양이처럼 먹다")
}
}