<드디어 최종 완성!!>
** Bus 클래스 **
package transportation;
import java.util.Random;
import javax.swing.JOptionPane;
public class Bus implements TransportationMark{
// private 필드는 다른 클래스에서 접근할 수 없으므로
// public getter와 setter를 만들어 주어야 한다.
// 따라서 외부에서 private필드에 접근하기 위해서는
// getter, setter를 사용하거나 생성자로 접근한다.
private String[] stops;
private String num;
public final int FEE = 1250;
public int depart_idx;
public Bus() {
}
public Bus(String[] stops, String num) {
//외부에서 전달된 정류소가 5군데가 아닐 시 막아준다.
if (stops.length == 5) {
this.stops = stops;
} else {
JOptionPane.showMessageDialog(null, "정류장은 5개입니다.");
//강제 종료
System.exit(0);
}
this.num = num;
}
public String[] getStops() {
return stops;
}
public void setStops(String[] stops) {
if (stops.length == 5) {
this.stops = stops;
} else {
JOptionPane.showMessageDialog(null, "정류장은 5개입니다.");
System.exit(0);
}
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
//출발지를 랜덤하게 조정
public void start() {
Random r = new Random();
depart_idx = r.nextInt(stops.length - 1);
}
//다른 지역에 있는 money를 수정해야 하므로
//값이 아닌 주소로 전달받는다.
//사용자가 선택한 도착지 번호도 전달받는다.
public int go(int[] money, int dest_idx) {
//Flag
int check = -1;
if (dest_idx - depart_idx <= 0) {
// 역방향 혹은 현재 위치한 정류소 선택(잘못 선택)
check = 0;
} else {
//사용자 돈을 pay메소드에서 검사
//잔액부족시 false
if (pay(money)) {
int i = 0;
//출발지 인덱스부터 도착지 전 정류장까지 반복하여 출력
for (i = depart_idx; i < dest_idx; i++) {
System.out.print(stops[i] + " > ");
try {Thread.sleep(1000);} catch (InterruptedException e) {;}
}
//마지막 도착지 출력
System.out.println(stops[i] + " > 도착");
//정상 운행
check = 1;
}
}
// -1 : 잔액부족, 0 : 잘못선택, 1 : 정상
return check;
}
public boolean pay(int[] money) {
boolean check = false;
//잔액이 부족하지 않으면 차감 후 잔고 출력
if (money[0] - FEE >= 0) {
money[0] -= FEE;
JOptionPane.showMessageDialog(null, "남은 잔액 : " + money[0] + "원");
check = true;
}
return check;
}
}
** Subway 클래스 **
package transportation;
import java.util.Random;
import javax.swing.JOptionPane;
public class Subway implements TransportationMark{
private String[] stops;
private String num;
public final int FEE = 1250;
public int depart_idx;
public Subway() {
}
public Subway(String[] stops, String num) {
if (stops.length == 7) {
this.stops = stops;
} else {
JOptionPane.showMessageDialog(null, "정류장은 7개입니다.");
System.exit(0);
}
this.num = num;
}
public String[] getStops() {
return stops;
}
public void setStops(String[] stops) {
if (stops.length == 7) {
this.stops = stops;
} else {
JOptionPane.showMessageDialog(null, "정류장은 7개입니다.");
System.exit(0);
}
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
public void start() {
Random r = new Random();
depart_idx = r.nextInt(stops.length);
}
public int go(int[] money, int dest_idx) {
int check = -1;
if (dest_idx - depart_idx == 0) {
// 현재 위치한 정류소 선택(잘못 선택)
check = 0;
} else if(dest_idx - depart_idx > 0) {
//정방향
if (pay(money)) {
int i = 0;
for (i = depart_idx; i < dest_idx; i++) {
System.out.print(stops[i] + " > ");
try {Thread.sleep(2000);} catch (InterruptedException e) {;}
}
System.out.println(stops[i] + " > 도착");
check = 1;
}
}else {
//역방향
if (pay(money)) {
int i = 0;
//출발지 인덱스가 더 크기 때문에
//도착지까지 가기 위해서는 1씩 감소를 해야한다.
for (i = depart_idx; i > dest_idx; i--) {
System.out.print(stops[i] + " > ");
try {Thread.sleep(2000);} catch (InterruptedException e) {;}
}
System.out.println(stops[i] + " > 도착");
check = 1;
}
}
// -1 : 잔액부족, 0 : 잘못선택, 1 : 정상
return check;
}
public boolean pay(int[] money) {
boolean check = false;
if (money[0] - FEE >= 0) {
money[0] -= FEE;
JOptionPane.showMessageDialog(null, "남은 잔액 : " + money[0] + "원");
check = true;
}
return check;
}
}
** Taxi 클래스 **
package transportation;
import java.util.Random;
public class Taxi implements TransportationMark{
//기본 요금
final int FEE = 3800;
//km당 요금
final int PER_KM = 1200;
private String name;
public Taxi() {}
public Taxi(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void go(int[] money, String destination) {
Random r = new Random();
// 1~10km
// 0~9 + 1
//랜덤한 km
int km = r.nextInt(10) + 1;
//마지막 1km는 금액이 정산되지 않기 때문에(pay()를 사용하지 않는다)
//미리 total에 적용시킨다.
int total = FEE + PER_KM;
System.out.print(destination + "까지의 남은 거리 : ");
int i;
for (i = km; i > 1; i--) {
//km당 1200원을 total에 누적
total += PER_KM;
System.out.print(i + "km > ");
try {Thread.sleep(500);} catch (InterruptedException e) {;}
}
System.out.println(i + "km > 도착");
//도착 후 잔액검사
if (!pay(money, total)) {
//잔액부족시 돈을 0원으로 만들고 메세지 출력
money[0] = 0;
System.out.println("잔액부족 / 경찰 출동중");
}
System.out.println("남은 잔고 : " + money[0] + "원");
}
public boolean pay(int[] money, int total) {
boolean check = false;
if (money[0] - total >= 0) {
check = true;
money[0] -= total;
}
return check;
}
}
** Stop 메인메소드 클래스 **
package transportation;
import java.util.Scanner;
public class Stop {
public static void main(String[] args) {
/*버스*/
String[] stops_41 = {"강남", "역삼", "선릉", "삼성", "종합운동장"};
String[] stops_141 = {"연신내", "녹번", "대조동", "박달고개", "역촌사거리"};
String[] stops_1001 = {"일산서부경찰서", "대화역", "주엽고교", "후곡마을", "행정복지센터"};
/*전철*/
String[] stops_line2 = {"서초", "방배", "사당", "낙성대", "서울대입구", "봉천", "신림"};
String[] stops_line3 = {"남부터미널", "교대" , "고속터미널", "잠원", "신사", "압구정", "옥수"};
/*버스 배열*/
Bus[] buses = {
new Bus(stops_41, "41"),
new Bus(stops_141, "141"),
new Bus(stops_1001, "1001")
};
/*전철 배열*/
Subway[] lines = {
new Subway(stops_line2, "2"),
new Subway(stops_line3, "3")
};
/*택시 배열*/
Taxi[] taxies = {
new Taxi("카카오 택시")
};
//up casting
TransportationMark[][] trans = {buses, lines, taxies};
Scanner sc = new Scanner(System.in);
//대중교통 인덱스
int row_choice = 0;
//사용자가 선택한 대중교통의 종류
int column_choice = 0;
int[] money = {10000};
int dest_idx = 0;
while(true) {
System.out.println("[대중교통]\n1.버스\n2.지하철\n3.택시\n4.나가기");
row_choice = sc.nextInt();
sc.nextLine();
if(row_choice == 4) {break;}
row_choice--;
while(true) {
int i;
//사용자가 선택한 대중교통 메뉴 출력
for (i = 0; i < trans[row_choice].length; i++) {
if(row_choice == 0) {
System.out.println(i+1+"."+((Bus)trans[row_choice][i]).getNum());
}else if(row_choice == 1) {
System.out.println(i+1+"."+((Subway)trans[row_choice][i]).getNum());
}else {
System.out.println(i+1+"."+((Taxi)trans[row_choice][i]).getName());
}
}
System.out.println(i+1+".대중교통 다시 선택");
column_choice = sc.nextInt();
sc.nextLine();
if(column_choice == i+1) {break;}
column_choice--;
int temp = 0;
//사용자가 선택한 대중교통이 버스일 때
if(trans[row_choice][column_choice] instanceof Bus) {
//down casting
//버스 필드에 접근하고자 할 때 up casting된 객체를 반드시
//down casting해야한다.
Bus bus = (Bus)trans[row_choice][column_choice];
bus.start();
//정류소를 출력하는 영역
for (i = 0; i < bus.getStops().length; i++) {
System.out.print(i+1+bus.getStops()[i] + " ");
}
//출발지를 출력하는 영역
System.out.println("\n출발지 : " + bus.getStops()[bus.depart_idx]);
dest_idx = sc.nextInt()-1;
//temp는 결과값을 담고 있다(-1, 0, 1)
temp = bus.go(money, dest_idx);
//사용자가 선택한 대중교통이 전철일 때
}else if(trans[row_choice][column_choice] instanceof Subway) {
Subway subway = (Subway)trans[row_choice][column_choice];
subway.start();
for (i = 0; i < subway.getStops().length; i++) {
System.out.print(i+1+subway.getStops()[i] + " ");
}
System.out.println("\n출발지 : " + subway.getStops()[subway.depart_idx]);
dest_idx = sc.nextInt()-1;
temp = subway.go(money, dest_idx);
//사용자가 선택한 대중교통이 택시일 때
}else {
Taxi taxi = (Taxi)trans[row_choice][column_choice];
System.out.print("도착지 : ");
taxi.go(money, sc.nextLine());
}
}
}
//1.대중교통을 선택(버스, 지하철, 택시 중 택 1)
//2.버스와 지하철은 어떤 것인지도 선택(41, 141, .... 중 택 1)
//1.과 2.에서 입력받은 정수가 각각 행과 열에 들어간다.
//택시일 경우 Flag를 사용해서 가려내고 go()만 사용해준다.
//// String[] stops = {"서초", "교대", "강남", "역삼", "선릉"};
//// String[] stops = {"서초", "교대", "강남", "역삼", "선릉", "삼성", "종합운동장"};
// int[] money = {10000};
// Taxi kakao = new Taxi("카카오택시");
//// Bus bus_41 = new Bus(stops, "41");
//// Subway line2 = new Subway(stops, "2");
// Scanner sc = new Scanner(System.in);
// System.out.print("도착지 : ");
//
// kakao.go(money, sc.nextLine());
//
//// bus_41.start();
//
//// line2.start();
//// for (int i = 0; i < bus_41.getStops().length; i++) {
//// System.out.print(i+1+bus_41.getStops()[i] + " ");
//// }
//// for (int i = 0; i < line2.getStops().length; i++) {
//// System.out.print(i+1+line2.getStops()[i] + " ");
//// }
//// System.out.println("\n출발지 : " + bus_41.getStops()[bus_41.depart_idx]);
//// System.out.println("\n출발지 : " + line2.getStops()[line2.depart_idx]);
//// System.out.println("도착할 정류소 번호를 입력하세요.");
//// if(bus_41.go(money, sc.nextInt()-1) != 1) {
//// if(line2.go(money, sc.nextInt()-1) != 1) {
//// System.out.println("다음 버스를 이용해주세요.");
//// }
}
}
** TransportationMark 인터페이스 **
package transportation;
//공통 타입이 없는 클래스들을 그룹화 하기 위한 목적
public interface TransportationMark {;}
1. 내부 클래스(inner class)
: 클래스 내부에 클래스를 선언하여 외부 클래스의 필드 접근에
용이하기 하기 위함.
내부 클래스의 필드를 사용하기 위해서는 외부 클래스 객체로
내부 클래스를 객체화 해야한다.
외부클래스명 외부객체명 = new 외부생성자();
외부클래스명.내부클래스명 내부객체명 = 외부객체명.new 내부생성자();
2. 내부 클래스를 사용하는 이유
: A클래스에서 b라는 작업이 자주 쓰이고, 이 작업은 B클래스를 만들어야
쉽게 관리할 수 있다. 하지만 다른 클래스에서는 b작업이 필요 없거나
외부에 노출시키고 싶지 않을 때 사용한다. 이것을 캡슐화라고 한다.
내부 클래스는 GUI(Graphic User Interface) 개발시 많이 사용된다.
예를 들어 하나의 클래스에 a라는 버튼과 b라는 버튼의 기능을 구현할 때
각각 클래스로 분리해서 만드는 것보다 내부 클래스로 만들어 사용하는 것이 적합!
3. 익명클래스 (Anonymous inner class)
: 이름은 없고 중괄호 영역만 존재한다.
일회성이기 때문에 이름이 없어도 무방하다.
하지만 메모리에 할당은 된다.
4. 오늘 실습코드
1) 내부클래스, 익명클래스 예제
** Cafe 인터페이스 **
package inner;
public interface Cafe {
String[] getMenu();
void setMenu(String[] menu);
void sell(String choice);
}
** 인터페이스 Cafe를 인터페이스 받은 CafeAdapter 추상 클래스**
package inner;
public abstract class CafeAdapter implements Cafe{
@Override
public String[] getMenu() {return null;}
@Override
public void setMenu(String[] menu) {}
@Override
public void sell(String choice) {}
}
** Road 메인 메소드 클래스 **
package inner;
public class Road {
public static void main(String[] args) {
StarBucks gangnam = new StarBucks();
StarBucks jamsil = new StarBucks();
jamsil.regist(new CafeAdapter() {
@Override
public void setMenu(String[] menu) {
// TODO Auto-generated method stub
super.setMenu(menu);
}
@Override
public String[] getMenu() {
// TODO Auto-generated method stub
return super.getMenu();
}
});
gangnam.regist(new Cafe() {
String[] menu = {"아메리카노", "카페라떼", "샌드위치"};
@Override
public void setMenu(String[] menu) {
this.menu = menu;
}
@Override
public void sell(String choice) {
for (int i = 0; i < menu.length; i++) {
if(menu[i].equals(choice)) {
System.out.println(menu[i] + "주문 완료");
}
}
}
@Override
public String[] getMenu() {
return menu;
}
});
}
}
2) 익명클래스 예제
** InnerTest 클래스 **
package inner;
class Out{
int outData;
public Out() {
System.out.println("외부 생성자 호출");
}
public void printOutData() {
System.out.println(outData);
}
public class In{
int inData;
public In() {
outData = 100;
System.out.println("내부 생성자 호출");
}
public void printData() {
printOutData();
System.out.println(inData);
}
}
}
public class InnerTest {
public static void main(String[] args) {
Out out = new Out();
Out.In in = out.new In();
in.inData = 600;
in.printData();
}
}
3) 내부클래스, 추상클래스가 사용되는 예제
** WindowTest 클래스 **
package inner;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class WindowTest {
public static void main(String[] args) {
JFrame window = new JFrame();
JButton btn = new JButton("눌러줘요");
window.setSize(500, 600);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int x = (d.width - window.getWidth()) / 2;
int y = (d.height - window.getHeight()) / 2;
window.setLocation(x, y);
btn.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
System.out.println("눌렸엉");
}
});
window.add(btn);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().setBackground(Color.ORANGE);
window.setVisible(true);
}
}
'웹_프론트_백엔드 > 단과' 카테고리의 다른 글
[단과_C] 2020.02.26 (0) | 2020.02.27 |
---|---|
[단과_C] 2020.02.25 (0) | 2020.02.26 |
[단과_C] 2020.02.24 (0) | 2020.02.25 |
[단과_JAVA] 2020.02.24 (0) | 2020.02.25 |
[단과_C] 2020.02.21 (0) | 2020.02.22 |