정구리의 우주정복
[Java] abstract ,down-casting 활용해보기 본문
오늘은 과일 관리 프로그램 만들어봤다 !
- 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를 통해 사용할 수 있게 된다 !!
'STUDY > K-DIGITAL' 카테고리의 다른 글
[MySQL] mysql 명령어들 정리 (2) | 2022.09.22 |
---|---|
[Java] abstract, extend, override, template method 사용해보기 (0) | 2022.09.10 |
[Java] 상속이랑 등등 (2) | 2022.09.06 |
[Java] 상속 , override 정복하기 (1) | 2022.09.05 |
[Javascript] mouse hover 시 글씨 나오게 하기 !! (0) | 2022.09.04 |