자바

[JAVA] 추상클래스

코딩하는둥이 2022. 12. 3. 17:02

추상 클래스(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입니다.