정구리의 우주정복

[Java] abstract ,down-casting 활용해보기 본문

STUDY/K-DIGITAL

[Java] abstract ,down-casting 활용해보기

Jungry_ 2022. 9. 10. 01:34
반응형

오늘은 과일 관리 프로그램 만들어봤다 !

 

  • Template.java  / 추상 클래스 !! 안에는 Input,output,modify,delete , scanner , cnt 가 정의되어 있다 
  • Score.java  / field 들이 정의되어있다, 이름 국어 영어 수학 총점 평균이 private 로 있고 getter 와 setter 가 있다
  • ScoreMain.java  / 프로그램이 동작하는 실행용 class
  • ScoreService.java / Main에서 동작하는 기능을 구현해놓은 service Template 을 상속한다

 

Template.java

package ch02.quiz.case01;

import java.util.Scanner;

public abstract class Template {

	public abstract	void input(Object[] o);
	public abstract void output(Object[] o);
	public abstract void modify(Object[] o);
	public abstract void delete(Object[] o);
	
	Scanner sc = new Scanner(System.in);
	int cnt = 0;
}

 

이친구는 abstract class( 추상 클래스)이다 !!

추상클래스란 ?

=>  abstract라는 것이 상속을 강제하는 일종의 규제라고 생각하자. 즉 abstract 클래스나 메소드를 사용하기 위해서는 반드시 상속해서 사용하도록 강제하는 것이 abstract다. 

 

다른 메소드들과는 다르게 function(){} 이 형태가 아니라 function(); 이런 형태를 띠고있다.

위 소스에서는 input, output, modify, delete 이렇게 4개가 추상클래스이고 (상속을 한다면 반드시 사용해야한다) 그 밖에도 scanner 와 cnt 변수를 만들어줬다 

 

Score.java

package ch02.quiz.case01;

public class Score {

	private String name;
	private int kor;
	private int eng;
	private int ma;
	private int total;
	private int avg;
	
	public int getKor() {
		return kor;
	}
	public int getEng() {
		return eng;
	}
	public int getMa() {
		return ma;
	}
	public int getTotal() {
		return total;
	}
	public int getAvg() {
		return avg;
	}
	public void setKor(int kor) {
		this.kor = kor;
	}
	public void setEng(int eng) {
		this.eng = eng;
	}
	public void setMa(int ma) {
		this.ma = ma;
	}
	public void setTotal(int kor,int eng,int ma) {
		this.total = kor+eng+ma;
	}
	public void setAvg(int total) {
		this.avg = total/3;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}

크게 어려운 부분은 없고 사용할 field 들을 private 형태로 만들어줬다 ! 그리고 getter 와 setter도 사용해줬음 !! setTotal 은 굳이 저렇게 안만들어도되는데 그냥 만들어봤다 ..

 

ScoreMain.java

package ch02.quiz.case01;



public class ScoreMain {
	public static void main(String[] args) {
		
		Object[] o = new Score[5]; //이거 그냥 Score 로 넣어줘도 상관없음 Object 가 큰거기 때문에 작은 Score 가 들어올 수있다 !!!(upcasting) 
		
		ScoreService ss = new ScoreService();
		
		while(true) {
			int menu = ss.menu();
			
			switch(menu) {
			case 0:
				System.out.println("END THE PROGRAM");
				return;
				
			case 1:
				ss.input(o); //object type은 다 받을 수 있어서 그냥 넣어줘도상관 없음 (여기서 자동으로 upcasting) !!! 그냥 service 에서 다운 캐스팅 해주면 된다 
				break;
			case 2:
				ss.output(o);
				break;
			case 3:
				ss.modify(o);
				break;
			case 4:
				ss.delete(o);
				break;
			}
			
		}
	}

}

실제로 동작하는 실행용 클래스이다 ! 

여기서 중요한 점은 Object[] o = new Score[5]; 여기 부분을 

Score[] o = new Score[5]; 로 한뒤 아래의 ss.input(o). 이렇게 사용할 수 있다는 점이다 !!!

 

아까 template.java 에서 input의 매개변수 타입을 object 로 지정해줘서 object type 으로 선언해야지 왜 score 로 하냐 !!!! 가 의문일 수 있지만 

클래스의 크기가 object 가 score 보다 더 크기 때문에 자동으로 upcasting 이 되어 상관없다 !!! 그냥 service에서 사용할때 downcasting 을 해주면 된다 !! object type 은 그냥 다 받을 수 있어서 상관없다 !!!!!    이해가 되었으려나 ..? 모르면 댓글 고고 (사실 나도 나름 이해한거라 이상할 수도있음) 

 

 

ScoreService.java

package ch02.quiz.case01;


public class ScoreService extends Template{	
	
	public int menu() {
		System.out.println("===== MENU =====");
		System.out.println("1. INPUT");
		System.out.println("2. OUTPUT");
		System.out.println("3. MODIFY");
		System.out.println("4. DELETE");
		System.out.println("0. END THE PROGRAM");
		System.out.print(">> ");
		return sc.nextInt();
	}



	@Override
	public void input(Object[] o) { //최상위와 우리가 만든 객체이기 때문에 downCasting
		Score[] s = (Score[]) o;
		
		if(cnt == o.length) {
			System.out.println("더이상 생성 안됨요 ㅋㅋ");
			return;
		}
		s[cnt] = new Score();
		System.out.print("이름 입력 >>>");
		s[cnt].setName(sc.next());
		
		System.out.print("국어 점수 입력 >>>");
		s[cnt].setKor(sc.nextInt());
		System.out.print("영어 점수 입력 >>>");
		s[cnt].setEng(sc.nextInt());
		System.out.print("수학 점수 입력 >>>");
		s[cnt].setMa(sc.nextInt());
		
		s[cnt].setTotal(s[cnt].getKor(),s[cnt].getEng(),s[cnt].getMa());
		s[cnt].setAvg(s[cnt].getTotal());
		

		cnt ++;
	}

	@Override
	public void output(Object[] o) {
		
		if(cnt == 0) {
			System.out.println("출력할게 없쪄요");
			return;
		}
		for(int i=0; i<cnt; i++) {
			Score s = (Score) o[i]; //이런 방법 사용할 수 있음 !!!!
			System.out.println("####"+ s.getName()+"####");
			System.out.println("국어 점수 >>> "+s.getKor());
			System.out.println("영어 점수 >>> "+s.getEng());
			System.out.println("수학 점수 >>> "+s.getMa());
			
			System.out.println();
		}
		
		
	}

	@Override
	public void modify(Object[] o) {
		Score[] s = (Score[]) o;
		
		if(cnt==0) {
			System.out.println("검색할 게 없어요 ");
			return;
		}
		System.out.print("수정하고 싶은 이름 입력 >>> ");
		String name = sc.next();
		for(int i=0; i<cnt; i++) {
			if(s[i].getName().equals(name)) {
				
				System.out.print("수정 할 국어 점수 입력 >>>");
				s[i].setKor(sc.nextInt());
				System.out.print("수정 할 영어 점수 입력 >>>");
				s[i].setEng(sc.nextInt());
				System.out.print("수정 할 수학 점수 입력 >>>");
				s[i].setMa(sc.nextInt());
				
				System.out.println("수정 완료 ");
				return;
				
			}
		}
		System.out.println("일치하는 이름이 없습니다요옹");
		
	}

	@Override
	public void delete(Object[] o) {
		Score[] s = (Score[]) o;
		if(cnt == 0) {
			System.out.println("삭제할게 없어용 !");
			return;
		}
		
		System.out.print("삭제하고자 하는 아이디 입력 >>>");
		String name = sc.next();
		
		for(int i=0; i<cnt; i++) {
			if(s[i].getName().equals(name)) {
				for(int j = i; j<cnt-1; j++) {
					s[j] = s[j+1];
				}
				cnt --;
				System.out.println("삭제 완료 ");
				return;
			}
		}
		System.out.println("삭제하고자 하는 아이디가 없습니다 !!!");
		
	}
	
	




}

 

우선 extends Template 를 했기 때문에 !무조건 input,output,modify,delete 를 oveerride 해줘야한다 !

=> 만약 override 했는데 사용하기 싫으면 어떡하나요 ??

==> 그냥 비워둬라 !!!! 그래도 에러 안나용 !!!

 

 input(Object[] o ) 부터 살펴보자 

Object 타입이기 때문에 우리가 원하는 Score 방식으로 사용하기 위해서는 Score 형태로 down-casting 해줘야한다

(큰거 -> 작은거 = down-casting)

 

downcasting 이후에는 그냥 똑같이 사용해주면 된다 .

하지만 input 은 다른 방식으로 구현할 수도있는데 

 

 

if(cnt == o.length) {

return;

}

Score s= new Score();

System.out.print("이름 입력 >>>");

s.setName(sc.next());

System.out.print("국어점수 입력 >>> ");

s.setKor(sc.nextInt());

o[cnt] = s;

cnt ++;   //이렇게 만들 수 도 있음 !!!

 

위에도 말했듯이 Object 가 더 크기 때문에 그 안에 Score 를 담을 수 있다 !! 따라서 input에서 굳이 down-casting 을 하지 않고 그냥 사용해 줄 수도있음 !!

 

output, modify, delete 는 모두 down-casting을 해야한다 ( 왜냐면 Score 의 메소드를 사용할거니까 !!!)

Score[] s = (Score[]) o; 이렇게 다운캐스팅 해주면 이제 s를 통해 사용할 수 있게 된다 !!

반응형
Comments