*본 내용은 [Do it! 자바 프로그래밍 입문] 책과 강의를 보고 공부하면서 요점 정리한 내용입니다.
추상 메서드를 포함한 클래스
(추상 메서드를 포함하고 있지 않다고 해도 추상 클래스가 될 수는 있다.)
추상 메서드는 구현코드없이 메서드의 선언만 있다.
public abstract void display(); // 추상 메서드 - 구현을 안하고 메서드를 선언만 하겠다는 의미
public void display() {} // 추상 메서드가 아니다. {}에 아무것도 작성하지 않아도 구현부가 있는 것으로 본다.
abstract 예약어를 사용한다. abstract로 선언된 메서드를 가진 클래스는 abstract로 선언 한다. 만약 모든 메서드가 구현코드가 있지만 클래스가 abstract로 선언된 경우 추상 클래스가 되고 new 할 수 없다.
추상 클래스는 new(인스턴스 화) 할 수 없다.
cf) concrete class 구현 클래스
추상 클래스는 상속을 위한 클래스이다.
추상 메서드는 하위 클래스가 구현해야만 하는 메서드이다.
하위 클래스에서 구체적으로 구현할 필요가 있을 때 상위 클래스에서 추상 메서드로 둔다.
구현된 메서드: 하위 클래스가 공통으로 사용할 수 있는 기능을 구현한다.
경우에 따라서는 하위 클래스가 재정의(overriding)할 수 있다.
Computer.java
package abstractex;
public abstract class Computer {
//추상 메서드
public abstract void display();
public abstract void typing();
//구현된 메서드 - 추상 클래스에서 일반 메서드도 구현 가능하다.
public void turnOn() {
System.out.println("전원을 켭니다.");
}
public void turnOff() {
System.out.println("전원을 끕니다.");
}
}
DeskTop.java
package abstractex;
public class DeskTop extends Computer{
@Override
public void display() {
System.out.println("DeskTop display()");
}
@Override
public void typing() {
System.out.println("DeskTop typing()");
}
}
NoteBook.java
package abstractex;
public abstract class NoteBook extends Computer {
@Override
public void display() {
System.out.println("NoteBook display()");
}
}
ComputerTest.java
package abstractex;
public class ComputerTest {
public static void main(String[] args) {
// Computer c1 = new Computer(); // 오류 발생, 추상클래스는 인스턴스화 불가능
Computer c2 = new DeskTop(); // 가능
// Computer c3 = new NoteBook(); // 불가능
Computer c4 = new MyNoteBook(); // 가능
NoteBook c5 = new MyNoteBook(); // 가능
c2.display();
c4.display();
}
}
실행 결과
DeskTop display()
NoteBook display()
public static final double PI = 3.14;
∙ final 변수는 값이 변경될 수 없는 상수이다.
∙ 프로젝트 구현시 여러 파일에서 공유해야 하는 상수 값은 하나의 파일에 선언하여 사용하면 편리하다.
∙ final 변수는 오직 한 번만 값을 할당할 수 있다.
final 메서드는 하위 클래스에서 재정의(overriding)할 수 없다.
final 클래스는 더 이상 상속되지 않는다.
예) java의 String 클래스
// 두가지 형태 모두 가능
public final void run() {}
final public void run() {}
Car.java
package template;
public abstract class Car {
public abstract void drive();
public abstract void stop();
public abstract void wiper();
public void washCar() {} // 훅메서드 - 필요에 의해 재정의 해서 쓸 수 있음
public void startCar() {
System.out.println("시동을 켭니다.");
}
public void turnOff() {
System.out.println("시동을 끕니다.");
}
//템플릿 메서드
public final void run() {
startCar();
drive();
wiper();
stop();
washCar(); // 훅메서드
turnOff();
}
}
ManualCar.java
package template;
public class ManualCar extends Car{
@Override
public void drive() {
System.out.println("사람이 운전합니다.");
System.out.println("사람이 핸들을 조작합니다.");
}
@Override
public void stop() {
System.out.println("사람이 브레이크로 정지합니다.");
}
@Override
public void wiper() {
System.out.println("사람이 수동으로 와이퍼를 조작합니다.");
}
// public void run() {} // 템플릿 메서드이므로 재정의 하려고 하면 오류 남
}
AICar.java
package template;
public class AICar extends Car{
@Override
public void drive() {
System.out.println("자율 주행합니다.");
System.out.println("자동차가 스스로 방향을 전환합니다.");
}
@Override
public void stop() {
System.out.println("자동차가 스스로 멈춥니다.");
}
@Override
public void wiper() {
System.out.println("비나 눈의 양에 따라 자동으로 조절됩니다.");
}
@Override
public void washCar() {
System.out.println("자동으로 세차가 됩니다.");
}
}
CarTest.java
package template;
public class CarTest {
public static void main(String[] args) {
Car myCar = new ManualCar();
myCar.run();
System.out.println("==============");
Car yourCar = new AICar();
yourCar.run();
}
}
실행 결과
시동을 켭니다.
사람이 운전합니다.
사람이 핸들을 조작합니다.
사람이 수동으로 와이퍼를 조작합니다.
사람이 브레이크로 정지합니다.
시동을 끕니다.
==============
시동을 켭니다.
자율 주행합니다.
자동차가 스스로 방향을 전환합니다.
비나 눈의 양에 따라 자동으로 조절됩니다.
자동차가 스스로 멈춥니다.
자동으로 세차가 됩니다.
시동을 끕니다.
(※ 추상 클래스, 추상 메서드는 이태리체로 표현한다.)
각 PlayerLevel 별 가능한 기능이 다르다.
단, 기능의 순서는 run(), jump(), turn()의 순서이다.
기능의 순서와 반복에 대한 구현은 go(int) 메서드에서 구현되어 있다.(템플릿 메서드)
각 레벨마다 run(), jump(), turn() 기능은 다르게 구현되어야 하므로 추상 메서드로 선언한다.
MainBoard.java
package gamelevel;
public class MainBoard {
public static void main(String[] args) {
Player player = new Player();
player.play(1); // 1번 점프
AdvancedLevel aLevel = new AdvancedLevel();
player.upgradeLevel(aLevel);
player.play(2); // 2번 점프
SuperLevel sLevel = new SuperLevel();
player.upgradeLevel(sLevel);
player.play(3); // 3번 점프
}
}
Player.java
package gamelevel;
public class Player {
private PlayerLevel level;
public Player() {
level = new BeginnerLevel();
level.showLevelMessage();
}
public PlayerLevel getLevel() {
return level;
}
public void upgradeLevel(PlayerLevel level) {
this.level = level;
level.showLevelMessage();
}
public void play(int count) {
level.go(count);
}
}
PlayerLevel.java
package gamelevel;
public abstract class PlayerLevel {
public abstract void run();
public abstract void jump();
public abstract void turn();
public abstract void showLevelMessage();
final public void go(int count) {
run();
for(int i = 0 ; i < count ; i++) {
jump();
}
turn();
}
}
BeginnerLevel.java
package gamelevel;
public class BeginnerLevel extends PlayerLevel {
@Override
public void run() {
System.out.println("천천히 달립니다.");
}
@Override
public void jump() {
System.out.println("jump 할 줄 모르지롱~");
}
@Override
public void turn() {
System.out.println("turn 할 줄 모르지롱~");
}
@Override
public void showLevelMessage() {
System.out.println("*****초보자 레벨입니다*****");
}
}
AdvancedLevel.java
package gamelevel;
public class AdvancedLevel extends PlayerLevel{
@Override
public void run() {
System.out.println("빨리 달립니다.");
}
@Override
public void jump() {
System.out.println("높이 jump 합니다.");
}
@Override
public void turn() {
System.out.println("turn 할 줄 모르지롱~");
}
@Override
public void showLevelMessage() {
System.out.println("*****중급자 레벨입니다*****");
}
}
SuperLevel.java
package gamelevel;
public class SuperLevel extends PlayerLevel {
@Override
public void run() {
System.out.println("겁나게 빨리 달립니다.");
}
@Override
public void jump() {
System.out.println("겁나게 높이 jump 합니다.");
}
@Override
public void turn() {
System.out.println("한 바퀴 돕니다.");
}
@Override
public void showLevelMessage() {
System.out.println("*****고급 레벨입니다*****");
}
}
실행 결과
*****초보자 레벨입니다*****
천천히 달립니다.
jump 할 줄 모르지롱~
turn 할 줄 모르지롱~
*****중급자 레벨입니다*****
빨리 달립니다.
높이 jump 합니다.
높이 jump 합니다.
turn 할 줄 모르지롱~
*****고급 레벨입니다*****
겁나게 빨리 달립니다.
겁나게 높이 jump 합니다.
겁나게 높이 jump 합니다.
겁나게 높이 jump 합니다.
한 바퀴 돕니다.