Java library softeware는 비정상적인 동작이 발생 했을 때 신호를 보내는 체계를 갖고 있다.
이를 throwing an exception이라고 한다.
예외적인 상황을 처리하는 코드를 제공해야하는데 이를 hadling the exception이라고 한다.
try-throw-catch
Java에서는 기본적으로 try-throw-catch를 사용하여 exception handling을 한다.
try에서는 기본적인 코드를 수행한다.
try문에서는 exception을 throw하는 코드를 포함할 수 있다.
throw 되는 경우 이후의 try 문 수행은 중단되고 catch 문으로 넘어가게 된다.
throw statement는 함수 호출과 유사하다.
throw new ExceptionClassName(SomeString);
ExceptionClassName 클래스의 객체가 생성된다.
throw 문은 함수를 호출하는 대신 catch block을 불러온다.
exception이 throw 되면 catch block 이 실행되기 시작한다.
catch block의 실행을 cathcing the exeception 혹은 handling the exception이라고 한다.
catch(Exception e)
{
ExceptionHandlingCode
}
e 는 catch block parameter이다.
이 매개변수는 두 가지 역할을 한다.
1. thrown exception 객체의 유형을 구체화한다.
2. thrown exception 객체를 잡기 위한 이름으로 사용된다.
<try-throw-catch 예시>
try
{
if(men == 0 && women == 0)
throw new Exception("Lesson is canceled. No students.");
else if (men ==0)
throw new Exception("Lesson is canceled. No men. ");
else if (women ==0)
throw new Exception("Lesson is canceled. No women.");
if (women >= men)
System.out.println("Each man must dance with " + women/(double)men + "women.");
else
System.out.println("Each woman must dance with " + men/(double)women + "men.");
}
catch(Exception e)
{
String message = e.getMessage();
System.out.println(message);
System.exit(0);
}
- 코드가 컴파일 시 binding 되는 경우를 early binding, run time시 binding 되는 것을 late binding 혹은 dynamic binding이라고 한다.
- Java는 late binding을 사용한다. (private, final, static method 는 제외)
final Modifier
- final 표기된 method는 오버라이드 될 수 없다. -> base class로 사용될 수 없다!
- final 이 표기된 경우 컴파일러가 early binding을 사용한다.
Late Binding with toString
Sale aSale = new Sale("tire gauge", 9.95);
System.out.println(aSale)
toString이 클래스에 정의되어있다면 객체가 System.out.println을 사용하여 올바르게 출력
-> tire gauge Price and total cost = $9.95 (late binding으로 동작)
public void println(Object theObject)
{
System.out.println(theObject.toString());
}
println 메서드는 Sale 클래스가 존재하기 이전에 정의되어있다.
하지만 late binding으로 인해 Object 클래스의 toString이 아닌 Sale 클래스의 toString 메서드가 사용된다.
Upcasting and Downcasting
Upcasting : 파생 클래스의 객체가 기초 클래스의 변수에 할당되는 것
Sale saleVariable; //기초 클래스
DiscountSale discountVariable = new DiscountSale("paint", 15,10); //파생 클래스
saleVariable = discountVariable; //Upcasting
System.out.println(saleVariable.toString());
-> late binding으로 toString은 Discount 클래스에 정의된 것을 사용한다.
먼저 Course class에 필요한 변수 (이름,교수,강의실번호,가능여부)를 선언하고 생성자를 초기화해준다.
- Timetable Class
- TimeTableAPP Class
- 크게 주어진 세 개의 클래스를 기반으로 timetable application을 구현한다.
- course class 는 시간표에 포함될 내용인 수업에 대한 속성과 메서드를 제공하는 클래스이다.
- timetable class는 강의 일정을 관리하는 메서드를 포함하는 클래스이다.
- timetableapp class는 main 함수를 포함하여 수업일정을 추가,확인 및 관리할 수 있도록 작성한 application 구현 클래스이다.
Implement
<Course Class>
package assignment;
import assignment.Course;
public class Course { //강의 속성에 사용하는 변수 선언
public String name;
public String professor;
public String roomNumber;
public boolean isValid;
//각각의 생성자
public Course(String name, String tutor, String room) {
this.name = name;
this.professor = tutor;
this.roomNumber = room;
}
public Course(String name) {
this.name = name;
}
public Course(Course copy) {
this.name = copy.name;
this.professor = copy.professor;
this.roomNumber = copy.roomNumber;
this.isValid = copy.isValid;
}
//get 함수
public String getName() {
return name;
}
public String getProfessor() {
return professor;
}
public String getRoomNumber() {
return roomNumber;
}
//set함수
public void setName(String name) {
this.name = name;
}
public void setProfessor(String professor) {
this.professor = professor;
}
public void setRoomNumber(String roomNumber) {
this.roomNumber = roomNumber;
}
//동일한 강의인지 확인하는 메서드
public boolean equals(Course s) {
if (this.name.equals(s.name) && this.professor.equals(s.professor) && this.roomNumber.equals(s.roomNumber)) {
return true;
}
return false;
}
// 강의명을 반환해주는 메서드
public String toString() {
return name;
}
// 강의명, 교수명, 강의실 정보를 반환해주는 메서드
public String getDetails() {
return "\nName : " + name + "\n" + "Tutor : " + professor + "\n" + "Room : " + roomNumber + "\n";
}
}
<TimeTable Class>
package assignment;
import java.util.Calendar;
import java.util.Scanner;
import assignment.Course;
public class TimeTable {
Course[][] timeTable = new Course[5][10];
//열거형 type 으로 요일 상수 정의
public enum DAYS {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY
}
//2차원 배열로 시간표 생성
public TimeTable() {
timeTable = new Course[DAYS.values().length][10];
initialize();
}
//시간표 초기화 (점심,저녁시간 고정값으로 설정)
private void initialize() {
for (int i = 0; i < timeTable.length; i++) {
for (int j = 0; j < timeTable[i].length; j++) {
if (j == 3) {
timeTable[i][j] = new Course(" LUNCH", "-", "-");
} else if (j == 7) {
timeTable[i][j] = new Course(" DINNER", "-", "-");
} else {
timeTable[i][j] = new Course(" ----", "-", "-");
}
}
}
}
//요일과 period를 받아 시간표에 입력하는 메서드
public String getSchedule(String day, int period) {
int dayIndex = DAYS.valueOf(day).ordinal();
Course course = timeTable[dayIndex][period-1];
return "At that time you have: " + course.getDetails();
}
// 강의 속성 정보를 받아 가능여부 판단
public boolean setSchedule(String day, int period, String name, String tutor, String room) {
if (period == 3 || period == 7) {
return false;
}
int dayIndex = DAYS.valueOf(day).ordinal();
timeTable[dayIndex][period-1].setName(name);
timeTable[dayIndex][period-1].setProfessor(tutor);
timeTable[dayIndex][period-1].setRoomNumber(room);
return true;
}
// 시간표 format 출력
public String toString() { //timetable 형태를 return
StringBuilder sb = new StringBuilder();
sb.append("\tMONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY\n");
for (int i = 0; i < timeTable[0].length; i++) {
sb.append((i + 1) + "\t");
for (int j = 0; j < timeTable.length; j++) {
sb.append(timeTable[j][i].getName() + "\t");
}
sb.append("\n");
}
return sb.toString();
}
//요일을 입력받아 해당 요일의 시간표를 반환하는 메서드
public String oneDaySchedule(String day) {
int dayIndex = DAYS.valueOf(day).ordinal();
String result = DAYS.values()[dayIndex] + "\n";
for (int j = 0; j < timeTable[dayIndex].length; j++) {
result += timeTable[dayIndex][j].getDetails() + "\t";
}
result += "\n";
return result;
}
//강의명을 입력 받아 요일을 반환하는 메서드
public String subjectSchedule(String sub) {
String result = "";
for (int i = 0; i < timeTable.length; i++) {
for (int j = 0; j < timeTable[i].length; j++) {
if (timeTable[i][j].getName().equals(sub)) {
result += "Subject: " + timeTable[i][j].getName() + "\n" + "Day: "+ DAYS.values()[i] + "\n" + "Lecture: "+ (j+1) + "\n" + "Professor: " + timeTable[i][j].getProfessor() + "\n" + "Room No: " + timeTable[i][j].getRoomNumber();
}
}
}
return result;
}
//날짜를 입력받아 calender class 객체에 저장후 객체 반환(calender class 사용)
public Calendar setInputDate(String date) {
int year = Integer.parseInt(date.substring(0, 4));
int month = Integer.parseInt(date.substring(4, 6)) - 1;
int day = Integer.parseInt(date.substring(6));
Calendar cal = Calendar.getInstance();
cal.set(year, month, day);
return cal;
}
}
<TimeTableApp Class>
package assignment;
import java.util.Calendar;
import java.util.Scanner;
public class TimeTableApp {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
String[] weeks = { "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY" };
Calendar cal = Calendar.getInstance();
TimeTable timeTable = new TimeTable();
int enter, period;
String name, day, tutorName, roomName, sub, str,date;
boolean check;
boolean when = true;
do {
System.out.println(timeTable.toString());
System.out.println("===============Main Menu================");
System.out.println("(1) Add a class to my time table");
System.out.println("(2) View the class at a specific period");
System.out.println("(3) View schedule of a specific class");
System.out.println("(4) TimeTable corresponding to input date");
System.out.println("(5) Exit the program");
System.out.println("===============Main Menu================");
enter = keyboard.nextInt();
switch (enter) {
case 1: { //강의 정보를 입력받아서 시간표에 저장
System.out.println("Please enter the day to add the class");
day = keyboard.next();
day = day.toUpperCase();
System.out.println("Please enter the period to add the class");
period = keyboard.nextInt();
System.out.println("Please enter the name of the class");
name = keyboard.next();
System.out.println("Please enter the name of the tutor");
tutorName = keyboard.next();
System.out.println("Please enter the name of the room ");
roomName = keyboard.next();
check = timeTable.setSchedule(day, period, name, tutorName, roomName);
if (check == true)
System.out.println("Class successfully added");
else
System.out.println("Class was NOT successfully added");
break;
}
case 2: { // 요일과 교시를 입력받아 해당 시간의 강의 속성을 출력
System.out.println("Please enter the day of the class");
day = keyboard.next();
day = day.toUpperCase();
System.out.println("Please enter the peroid of the class");
period = keyboard.nextInt();
System.out.println(timeTable.getSchedule(day.toString(), period));
break;
}
case 3: { // 강의명을 입력받아 해당 강의 정보를 출력
System.out.println("Please enter the class name");
sub = keyboard.next();
str = timeTable.subjectSchedule(sub);
if (str.isEmpty()) {
System.out.println("There are no class");
break;
} else {
System.out.println(str);
}
break;
}
case 4: { //날짜를 입력받아 해당하는 요일의 시간표를 출력
System.out.println("Enter the date:");
date = keyboard.next();
cal = timeTable.setInputDate(date);
if (cal.get(Calendar.DAY_OF_WEEK) - 1 == 0 || cal.get(Calendar.DAY_OF_WEEK) - 1 == 6) {
System.out.println("There are no schedule");
break;
} else {
System.out.println(timeTable.oneDaySchedule(weeks[cal.get(Calendar.DAY_OF_WEEK) - 1]));
}
break;
}
case 5: { // 프로그램 종료
when = false;
break;
}
default:
System.out.println("Try again");
}
} while (when);
}
}