[JAVA] 추상클래스
추상 클래스(abstract class)
- 추상 메서드를 포함된 클래스
- 추상 매서드는 구현 코드 없이 매서드의 선언만 있음
EX) abstract int add(int x, int y) ;
// {}부분이 구현 내용 추상매서드 X
- abstract 예약어 사용
- 추상 클래스는 new (인스턴스화) 할 수 없음
cf) concrete class
// 두개의 추상 매서드 두개의 구현된 매서드를 가진 추상 클래스
// 선언된 추상클래스의 바탕으로 하위 클래스가 기반한 클래스를 구현
package abstractex;
public abstract class Computer{
public abstract void display();
public abstract void typing();
// public abstract int add(int x, int y); // 두개의 int를 받아서 그 결과을 합으로 반환하는 매서드
public void turnOn() {
System.out.println("전원을 킵니다.");
}
public void turnOff(){
System.out.println("전원을 끕니다.");
}
}
//모두 구현함
package abstractex;
public class DeskTop extends Computer{
@Override
public void display(){
System.out.println("DeckTop display()");
}
@Override
public void typing(){
System.out.println("DeckTop Typing()");
}
}
//하나만 구현
package abstractex;
public abstractex class NoteBook extends Computer{
@Override
public void display(){
System.out.println("NoteBook display()");
}
package abstractex;
public abstractex class MyNoteBook extends NoteBook{
@Override
public void typing(){
System.out.println("MyNoteBook Typing()");
}
}
추상클래스 만드는 이유
- 상속하기 위함
package abstractex;
public class ComputerTest {
public static void main(String[] args){
// Computer c1 = new Computer(); 인스턴스 생성 불가능
Computer c2 = new DeskTop();
// Computer c3 = new NoteBook(); //인스턴스 생성 불가능
NotBook c4 = new MyNoteBook();
c2.display();
c4.display();
}
}
추상 클래스와 탬플릿 매서드
- 탬플릿 메서드
: 추상 매서드나 구현된 매서드를 활용하여 전체 기능의 흐름(시나이로)을 정의하는 매서드
- final로 선언하면 하위클래스에서 재정의 할 수 없음
- 프레임 워크에서 많이 사용되는 설계 패턴
- 추상 클래스로 선언된 상위 클래스에 탬플릿 매서드를 활용하여 전체적인 흐름을 정의하고
하위 클래스에서 다르게 구현되어야 하는 부분은 추상 매서드를 선언해서 하위 클래스가 구현하도록 함
package template;
public abstract class Car {
public abstract void drive();
public abstract void stop();
public abstract void wiper();
public abstract void washcar() {}
public void startCar()
{
System.out.println("시동을 켭니다");
}
public void turnOff()
{
System.out.println("시동을 끕니다.");
}
final public void run()
{
startCar();
drive();
wiper();
stop();
washCar();
turnOff();
}
}
PlayerLevel 클래스
- 각 레벨마다 rin(), jump(), trun() 기능은 다르게 구현디어야 하므로 추상 메서드로 선언
- final로 선언된 go() 메서드에서 각 순서와 반복 횟수를 구현함(탬플릿 메서드)
public abstrat class PlayerLevel{
public abstract void run();
public abstract void jump();
public abstract void trun();
public abstract void showLevelMessage();
final public void go(int count){ // 재정의되면 안되므로 final로 선언
run();
for(int i =0; i < count; i++){
jump();
}
trun();
}
}
템플릿 메서드 구현
- 각 PlayerLevel 별 가능한 기능은 다름
- 단, 기능의 순서는 run(), jump(), trun()의 순서임
- 기능의 순서와 반복에 대한 구현은 go(int) 메서드에서 구현되어 있음 (템플릿 메서드)
package gamelevel;
public class MainBoard{
public static void main(String[] args){
Player.player = new Player();
player.play(1);
AdvancedLevel aLevel = new AdvancedLevel();
player.upgradeLevel(aLevel);
player.play(2);
SuperLevel sLevel = new superLevel();
player.upgradeLevel(sLevel);
player.play(3);
}
}
package gamelevel;
public abstract class playerLevel{
public abstract void run();
public abstract void jump();
public abstract void trun();
public abstract void showLevelMessage();
final public void go(int count){
run();for(int i =0; i < count; i++){
jump();
}
trun();
}
package gamelevel;
public class Player{
private PlayerLevel level;
public Player(){
level = new BeginnerLevel();
level.showLevelMessage();
}
public PlayLevel getLevel(){
return level;
}
public void upgradeLevel(PlayerLevel level){
this.level =level;
level.showLeveMessage();
}
public void play(int count){
level.go(count);
}
}
package gamelevel;
public class SuperLevel extends PlayerLevel{
@overeide
public void run(){
System.out.println(" 겁나게 빠르게 달립니다.");
}
@overeide
public void jump(){
System.out.println("겁나게 높게 jump 합니다.");
}
@overeide
public void trun(){
System.out.println("한바퀴를 돕니다.");
}
@overeide
public void showLevelMessage(){
System.out.println("고급 레벨입니다.");
}
}
package gamelevel;
public class MainBoard{
public static void main(String[] args){
Player.player = new Player();
player.play(1);
AdvancedLevel aLevel = new AdvancedLevel();
player.upgradeLevel(aLevel);
player.play(2);
SuperLevel sLevel = new superLevel();
player.upgradeLevel(sLevel);
player.play(3);
}
}
package gamelevel;
public abstract class playerLevel{
public abstract void run();
public abstract void jump();
public abstract void trun();
public abstract void showLevelMessage();
final public void go(int count){
run();for(int i =0; i < count; i++){
jump();
}
trun();
}
package gamelevel;
public class Player{
private BeginnerLevel level_1;
private AdvancesLevel level_2;
private SuperLevel level_3;
public Player(){
level = new BeginnerLevel();
level.showLevelMessage();
}
public PlayLevel getLevel(){
return level;
}
public void upgradeLevel(PlayerLevel level){
this.level =level;
level.showLeveMessage();
}
public void play(int count){
//level.go(count);
}
}
package gamelevel;
public class BeginnerLevel extends PlayerLevel{
@overeide
public void run(){
System.out.println(" 천천히 달립니다.");
}
@overeide
public void jump(){
System.out.println("jump 할 줄 모릅니다.");
}
@overeide
public void trun(){
System.out.println("turn 할 줄 모릅니다.");
}
@overeide
public void showLevelMessage(){
System.out.println("초보자 레벨입니다.");
}
}
final 예약어
- final 변수는 값이 변경될 수 없는 상수임
: public static final double PI = 3.14;
- final 변수는 오직 한 번만 값을 할당할 수 있음
- final 메서드는 하위 클래스에서 재정의(overriding) 할 수 없음
- final 클래스는 더 이상 상속되지 않음
ex) java의 String 클래스
여러 자바 파일에서 공유하는 상수 값 정의하기
- 프로젝트 구현시 여러 파일에서 공유해야 하는 상수 값은 하나의 파일에 선언하여 사용하면 편리함
public class Define{
public static final int MIN = 1;
public static final int MAX = 9999;
public static final int ENG = 1001;
public static final int MATH = 2001;
public static final int double PI = 3.14;
public static final int String GOOD_MORING = "Good Morning!";
}
public class UsingDefine {
public static void main(String[] args){
System.out.println(Define.GOODNORNING); // static으로 선언했으므로 인스턴스를 생성하지 않고 클래스 이름으로 참조 가능
System.out.println("최솟값은" + Define.MIN + "입니다.");
System.out.println("최댓값은" + Define.MAX + "입니다.");
System.out.println("수학 과목 코드 값은" + Define.MATH + "입니다.");
System.out.println("영어 과목 코드 값은" + Define.ENG + "입니다.");
}
}
// 결과
// Good Morning!
// 최솟값은 1입니다.
// 최댓값은 9999입니다.
// 수학 가목 코드 값은 2001입니다.
// 영어 과목 코드 값은 1001입니다.