JAVA-19

이강민·2021년 10월 7일
0

JAVA 기초 1

목록 보기
19/20
post-thumbnail

추상클래스(불완전한 클래스)

추상클래스란?

  1. 추상적인 내용만 정의하고 있는 클래스로 구체적인 내용은 하위 클래스에서 구현되도록 해놓은 클래스 (하위 클래스에서 무조건 상위 클래스의 메소드들을 재정의 한다)
  2. 추상클래스는 (부모)클래스들의 (자식)공통요소들을 가상화 시켜 놓는다.
  3. 부모 추상클래스의 역할은 단지 자식 클래스를 만들때 도와주는 역할을 수행하기 위해 존재한다.(다형성)
  4. 바디를 가지지 않는 메소드를 추상 메소드라고 하며, abstract 키워드가 앞에 붙는다.
    하지만 일반 메소드도 선언 가능하다.

추상클래스 선언

abstraact 추상클래스명{
	abstract 추상메소드명();
};

추상메소드는 자식클래스에서 강제적으로 반드시 재정의 해야한다.

추상클래스로 코드작성하기

무엇을 만들지 생각하기.

넓이를 무조건 재정의 하여 사용해야하는 모양 클래스를 만들고 각각 네모 클래스, 세모 클래스를 만들어 보자
1. abstract를 붙인 클래스를 만들어주고 재정의 해야하는 메소드를 만들면 된다. 우리는 showArea라는 메서드를 매개변수로 가로 길이와 세로길이를 받고 각각 실수형으로 받자.

public abstract class Shape {
	//실수형을 받기 위해 실수형 초기화
	double area;
	
    //무조건 재정의 해야하는 메소드
	abstract void showArea(double w, double h);
	
    //재정의 되는 것을 막아서 사용만 해야되는 메소드
	final void function(){
	System.out.println("추상 클래스의 일반 메서드입니다아아아아아");
	}
}
  1. 네모 세모 클래스를 만들고 모양클래스를 상속받아보자
    상속을 받을 때마다 재정의 하지 않으면 오류가 난다. 각 면적을 구하는 공식을 적어 재정의하자
class Rect extends Shape{

	@Override
	void showArea(double w, double h) {
		area = w*h; //넓이
		System.out.println("넓이" + area+ "cm²");
	}
}

class Tri extends Shape{
	@Override
	void showArea(double w, double h) {
	area = (w*h)/2;
	System.out.println("넓이" + area+ "cm²");
	}
}
  1. 이제 면적을 출력해보자
    두가지 방법으로 출력이 가능한데 먼저 new로 초기화 하는 방법과 바로 new를 붙여 사용하는 방법이 있다.
public class Board {
	public static void main(String[] args) {
		//첫번째 방법
        Rect re = new Rect();
		re.showArea(10, 50);
		
        //new 자식클래스명()를 사용하여 바로 값을 출력
		//new Rect().showArea(10,  50);
		new Tri().showArea(5, 1);
	}
}

대중교통예매하기(TMS) 만들기

예매하기 만들기 조건

  1. 이용할 대중교통을 선택하게 만들고
  2. 버스와 지하철 버튼을 만든다음 출발지는 랜덤으로 선택되고
  3. 출발지와 도착지가 같지 않도록 구현
  4. 버스는 정방향만 가능, 지하철은 역방향도 가능
  5. 역은 다음과 같다 <덕소, 상봉, 한남, 강남>

클래스는 어떻게 만들까?

  1. 클래스는 생성된 각 메서드를 무조건 이용하게 하는 추상메서드를 만들자.
  2. 그리고 클래스는 추상클래스부분, 버스클래스, 지하철클래스, 이용하는 클래스로 만들자

VIEW단에서 어떤 기능이 필요할까?

  1. 버스요금과 지하철 요금을 각각 만들고
  2. 지갑을 만들어 버스를 이용할 때마다 지갑에서 요금만큼 빠지게 만든다음
  3. 목적지로 이동하는 메서드를 만들자 (go메서드)
  4. 요금, 지갑도 관리하는 메서드도 필요하겠다. (pay메서드)
  5. 목적지에 도착하면 목적지를 알려주는 메서드도 만들자 (destMsg)

코드 작성하기

  1. 먼저 클래스를 만들어보자 클래스는 Public, bus, subway 그리고 이것을 출력할 Traffic클래스를 만든다. Public 클래스 먼저 보자
    Public 클래스를 추상 클래스로 만들고 추상메소드를 만들어 다른 상속받은 클래스에서 재정의 하도록 했다.
public abstract class Public {
	abstract void go();
	abstract void pay();
	abstract void destMsg();
}
  1. 다음은 bus 클래스를 만들어보자 public의 메소드를 재정의하기위해 public을 상속받고 각 메소드를 재정의 할 준비를 하자
package tms;

public  class Bus extends Public{
	
	@Override
	void go() {

	}

	@Override
	void pay() {
	}

	@Override
	void destMsg() {
	}
	
}
  1. 메소드를 재정의 할 준비가 끝났으면 먼저 재정의할 메소드를 정하자, pay메소드를 수정하자
    pay메소드는 외부 변수에서 money를 받고 이 money에서 feed만큼 누적감소 시키고 다시 money를 리턴하면 되겠다. 또한 리턴값이 int이니 public에도 수정된 타입과 매개변수를 적용하자
Public 클래스
	abstract int pay(int money);

bus 클래스
@Override
	int pay(int money) {
		money -= feed;
		return money;
	}
  1. 다음은 go메소드를 수정하자 go 메소드는 처음에 출발지를 랜덤으로 받아야 되니 랜덤을 받을 값들이 필요하다. 각 정류장들은 여기서도 쓰이고 다른 클래스에도 쓰이니 public에다가 정류장 클래스를 만들고 랜덤을 준비하자. 랜덤을 쓰기위해 index를 초기화하여 r.next에 담으면 되는데 이때 랜덤 길이는 만들어진 정류장들의 배열 길이만큼 하면 되겠다.
public 클래스 
	String [] arStation  = {"덕소", "상봉", "한남","강남"};

 bus클래스
@Override
	String go(int btnIndex, int money) {
	int index=0;
	Random r = new Random();
	index = r.nextInt(arStation.length);
}
  1. 그리고 목적지를 생각해보면 btnIndex로 매개변수로 받아올 것이다. 따라서 랜덤을 반복시키다가 index < btnIndex를 만족시키면 break를 하면된다. btnIndex를 매개변수로 받고 또한 money를 받앋와서 money가 feed보다 적을 때 즉 둘의 값을 뺀값이 0보다 작을 때 result와 그 외에 result 값에 결과를 담아서 result를 리턴 시키면 되겠다.
@Override
	String go(int btnIndex, int money) {
	int index=0;
    String result = "";
	Random r = new Random();
	while(true) {
		index = r.nextInt(arStation.length); //출발지
		if(index < btnIndex) break; //index가 btnIndex보다 작아야 랜덤이 결정된다
		}
        if(money-feed < 0) {
			result = "잔액부족";
		}else {
      }
}
  1. else에는 어떤 값들이 들어갈까? else에는 잔액이 충분할때 들어가면 되며 result에 pay(money)를 담고 콤마로 구분하여 출발 > 경유 > 목적 이라는 결과를 담으면 되겠다.
    출발지가 만들어지고 목적지를 선택하면 목적지 - 출발지 만큼 이동해야 된다.
    for구문으로 목적지 - 출발지 만큼 반복시키고 arStation[index+i] 를 담으면 되는데 출발지는 먼저 담아내자 그러면 index + i +1 이 된다. 또한 > 이라는 값이 마지막에 붙으니 삼항연산자로 빼주자 (목적지-출발지는 편의를 위해 cnt로 변수선언했다.)
String go(int btnIndex, int money) {
		int index=0;
		int cnt = 0;
		String result = "";
		//btnIndex : 목적지, index : 출발지
		Random r = new Random();
		
		while(true) {
		index = r.nextInt(arStation.length); //출발지
		if(index < btnIndex) break; //index가 btnIndex보다 작아야 랜덤이 결정된다
		}
		cnt = btnIndex-index;
		if(money-feed < 0) {
			result = "잔액부족";
		}else {
			result = "" + pay(money) + ",";
			result += arStation[index] + ">";
			for (int i = 0; i < cnt; i++) {
				result += i == cnt-1 ? arStation[index+i+1]: arStation[index+i+1]+">";
			}
		}
		return result;
	}
  1. 목적지를 나타내는 메소드를 재정의 해보자 이 메소드는 바로 목적지가 선택되면 메시지를 띄우게 만들어 주자. 그리고 이 메소드를 go메소드에서 실행시켜 주면 된다.
..생략..(go메소드)
				}
			destMsg(arStation[btnIndex]);
		}
		return result;
}

@Override
	void destMsg(String destination) {
			JOptionPane.showMessageDialog(null, destination + "에 도착하였습니다" );
	}
  1. 이제 Traffic에 만들어보자 Bus 클래스를 new로 초기화하고 optionDialog로 대중교통을 선택하게 만들고 이 값을 choice에 담자, 그리고 btnIndex도 optionDialog로 만들자.
    또한 while로 감싸 반복시키고 choice는 switch에 담아내자
public class Traffic {
	public static void main(String[] args) {
    Bus bus = new Bus();
    String [] arTraffic = {"버스", "지하철"};
    int choice = 0;
    int money = 10000;
    
    while(true) {
	choice = JOptionPane.showOptionDialog(null, "대중교통을 선택해주세요", "TMS", JOptionPane.DEFAULT_OPTION, 
						JOptionPane.PLAIN_MESSAGE, null, arTraffic, null);
	if(choice==-1) break;
	int btnIndex = JOptionPane.showOptionDialog(null, "도착지를 선택하세요", "TMS", JOptionPane.DEFAULT_OPTION, 
						JOptionPane.PLAIN_MESSAGE, null, bus.arStation, null);
			
	//버스일때 덕소도착은 막아야겠다
	if(choice == 0 && btnIndex ==0) {
	JOptionPane.showMessageDialog(null, "도착지는 덕소 다음 정류장부터 가능합니다.");
	continue;
	}
	switch(choice) {
		case 0 : 
			break;
		case 1 :
			break;
			}
		}
	}
}
  1. result는 잔액부분과 결과부분이 2개로 나뉘어져 있으니 배열로 길이가 2만큼 선언해주고
    case0에 결과를 담아내자, 또한 if조건문을 사용하여 잔액부족 메시지와 결과 메시지를 각가 만들고 money는 정수형으로 형변환해서 money에 담아내자
String [] result  = new String [2];

case 0 : 
	result = bus.go(btnIndex, money).split(",");
		if(result[0].equals("잔액부족")) {
			JOptionPane.showMessageDialog(null, "잔액이 부족합니다");
		}else {
			money = Integer.parseInt(result[0]);
			JOptionPane.showMessageDialog(null, "남은 잔액 : " +money + "\n" + result[1]);
		}
		break;
  1. 이번에 지하철을 만들자 지하철은 버스와 달리 역방향으로도 가능하니 랜덤 선언 부분에서 index와 btnIndex가 같지만 않으면 되고 cnt>0 인 조건과 아닐때 조건에서 각각 index-로 이동하냐와 index+로 이동하냐의 차이이다. 또한 cnt가 < 0이면 -1를 곱하여 양수로 만들어 사용한다.
package tms;

import java.util.Random;

import javax.swing.JOptionPane;

public class Subway extends Public{
int feed = 1500;
	
	@Override
	String go(int btnIndex, int money) {
		int index=0;
		int cnt = 0;
		String result = "";
		//btnIndex : 목적지, index : 출발지
		Random r = new Random();
		
		while(true) {
		index = r.nextInt(arStation.length); //출발지
		if(index == btnIndex) System.out.println("출발지와 목적지가 같습니다. \n 다시 실행됩니다");
		if(index != btnIndex) break; //index가 btnIndex보다 작아야 랜덤이 결정된다
		}
		
		cnt = btnIndex-index;
		
		if(money-feed < 0) {
			result = "잔액부족";
		}else {
			result = "" + pay(money) + ",";
			result += arStation[index] + ">";
			if(cnt > 0) {
				for (int i = 0; i < cnt; i++) {
					result += i == cnt-1 ? arStation[index+i+1]: arStation[index+i+1]+">";				
				}
			}else {
				cnt *= -1;
				for (int i = 0; i <cnt; i++) {
					result += i == cnt -1 ? arStation[index-i-1] : arStation[index-i-1] + ">";
				}
			}
			destMsg(arStation[btnIndex]);
		}
		return result;
	}

	@Override
	int pay(int money) {
		money -= feed;
		return money;
	}

	@Override
	void destMsg(String destination) {
			JOptionPane.showMessageDialog(null, destination + "에 도착하였습니다" );
	}
}
  1. Traffic클래스에서 bus와 동일하게 new 초기화와 case를 작성한다.
    case 작성시 결과가 콤마로 담겨있으니 split을 시켜 result 배열에 다시 담아 사용한다.
Subway sub = new Subway();
       case 1 :
	result = sub.go(btnIndex, money).split(",");
	if(result[0].equals("잔액부족")) {
		JOptionPane.showMessageDialog(null, "잔액이 부족합니다");
	}else {
		money = Integer.parseInt(result[0]);
		JOptionPane.showMessageDialog(null, "남은 잔액 : " +money + "\n" + result[1]);
	}
	break;
  1. 지금까지 작성한 Traffic 클래스와 bus클래스이다
package tms;

import javax.swing.JOptionPane;

public class Traffic {
	public static void main(String[] args) {
		Bus bus = new Bus();
		Subway sub = new Subway();
		String [] arTraffic = {"버스", "지하철"};
		int choice = 0;
		int money = 10000;
		String [] result  = new String [2];
		
		while(true) {
			choice = JOptionPane.showOptionDialog(null, "대중교통을 선택해주세요", "TMS", JOptionPane.DEFAULT_OPTION, 
													JOptionPane.PLAIN_MESSAGE, null, arTraffic, null);
			if(choice==-1) break;
			int btnIndex = JOptionPane.showOptionDialog(null, "도착지를 선택하세요", "TMS", JOptionPane.DEFAULT_OPTION, 
													JOptionPane.PLAIN_MESSAGE, null, bus.arStation, null);
			
			//버스일때 덕소도착은 막아야겠다
			if(choice == 0 && btnIndex ==0) {
				JOptionPane.showMessageDialog(null, "도착지는 덕소 다음 정류장부터 가능합니다.");
				continue;
			}
			switch(choice) {
			case 0 : 
				result = bus.go(btnIndex, money).split(",");
				if(result[0].equals("잔액부족")) {
					JOptionPane.showMessageDialog(null, "잔액이 부족합니다");
				}else {
					money = Integer.parseInt(result[0]);
					JOptionPane.showMessageDialog(null, "남은 잔액 : " +money + "\n" + result[1]);
				}
				break;
			case 1 :
				result = sub.go(btnIndex, money).split(",");
				if(result[0].equals("잔액부족")) {
					JOptionPane.showMessageDialog(null, "잔액이 부족합니다");
				}else {
					money = Integer.parseInt(result[0]);
					JOptionPane.showMessageDialog(null, "남은 잔액 : " +money + "\n" + result[1]);
				}
				break;
			}
		}
	}
}
package tms;

import java.util.Random;

import javax.swing.JOptionPane;

public  class Bus extends Public{
	int feed = 1200;
	
	@Override
	String go(int btnIndex, int money) {
		int index=0;
		int cnt = 0;
		String result = "";
		//btnIndex : 목적지, index : 출발지
		Random r = new Random();
		
		while(true) {
		index = r.nextInt(arStation.length); //출발지
		if(index < btnIndex) break; //index가 btnIndex보다 작아야 랜덤이 결정된다
		}
		cnt = btnIndex-index;
		if(money-feed < 0) {
			result = "잔액부족";
		}else {
			result = "" + pay(money) + ",";
			result += arStation[index] + ">";
			for (int i = 0; i < cnt; i++) {
				result += i == cnt-1 ? arStation[index+i+1]: arStation[index+i+1]+">";
			}
			destMsg(arStation[btnIndex]);
		}
		return result;
	}

	@Override
	int pay(int money) {
		money -= feed;
		return money;
	}

	@Override
	void destMsg(String destination) {
			JOptionPane.showMessageDialog(null, destination + "에 도착하였습니다" );
	}
	
}
profile
AllTimeDevelop

0개의 댓글

관련 채용 정보