220624 TIL

Yeoni·2022년 6월 26일
0

국비교육TIL

목록 보기
18/41

국비교육 18일차 Java : Final, Interface, Exception

1. Final

  • final은 한번 주어진 값을 변경하지 못하게 고정할 때 사용한다.
  • final 메소드는 자식클래스에서 오버라이딩이 불가능하다.
  • final은 public final class Final_test { } 과 같이 클래스에도 사용될 수 있는데, final로 되어진 클래스는 부모 클래스가 될 수 없다.

2. Interface

1) Interface란?

  • 인터페이스는 오로지 미완성 메소드와 final 변수로만 이루어진 field가 있는 경우를 말한다. 인터페이스에 오는 메소드는 무조건 미완성 메소드이기 때문에 일반 메소드와 같이 중괄호{ } 가 오지 않는다.
    ※인터페이스에서 field는 거의 사용을 안하긴 한다. 왜냐하면 변수가 바뀌지 않는 field는 거의 없기 때문이다.

2) Interface의 사용

  • 인터페이스에서의 미완성 메소드와 field의 접근제한자는 오직 public으로만 가능하다.
  • 인터페이스에서 field 생성 시, public final이 생략되어 있으며, 미완성 메소드 생성 시, public abstract 가 생략되어져 있다.
  • 인터페이스는 목차와 같은 느낌으로, 인터페이스에 메인에서 사용할 메소드명을 지정해주어 추후 유지보수가 원활하도록 만들어 준다.
  • 인터페이스를 사용할 때, 부모클래스에서 인터페이스에 있는 미완성 메소드를 재정의하지 않을 경우
    - 이 경우 부모클래스에서 인터페이스를 구현해준 다음, 자식 클래스에서 메소드의 재정의(override)가 필요하다. 부모 클래스는 인터페이스의 미완성 메소드를 재정의 해주지 않았기 때문에 미완성 클래스(abstract)가 되게 된다.

3) Interface의 구현(Implements)

  • 클래스에서 implements(구현) 해주게 되면 인터페이스에 있는 추상 메소드를 반드시 클래스에서 사용해주어야 한다.

  • 인터페이스

public interface Inter_example {
	double ex(double a); 	// 인터페이스에 생성되는 메소드는 미완성 메소드
}
  • 클래스
public class Example implements Inter_example {
	@Override 	
	// 인터페이스에 있는 미완성 메소드는 반드시 클래스에서 재정의 되어야 한다.
	public double ex(double a) {
		return 0;
	}
}
  • 메인 클래스
public static void main(String[] args) {
	
	// 클래스로 인스턴스 받아오기
	Example ep = new Example();
	System.out.println(ep.ex(1)); 	// 0.0
	
	
	// 인터페이스로 인스턴스 받아오기
	Inter_example ep1 = new Example();
	System.out.println(ep1.ex(1)); // 0.0
	/*
	 	>>> 다형성(Polymorphism) <<<	 
		인터페이스로 구현된 클래스의 객체는 그 인터페이스의 타입으로 받을 수 있다는 것이 다형성(Polymorphism)이다.
	 	인스턴스를 만들 때는, 인터페이스를 더 자주 사용하게 되는데 
	 	왜냐하면 인터페이스는 목차같은 역할이기 때문에 인스턴스의 메소드들이 다 각 클래스 안에 있기 때문이다.  
	 	인스턴스를 받아오는 것은 인터페이스이지만 실제로 작동하는 것은 각 클래스에서 오버라이딩 된 메소드들이다. 
	 */
	
	
	// 배열로 인스턴스 받아오기
	Inter_example[] ex_arr = new Inter_example[3]; 		
	// 객체를 만든 것이 아니라 배열을 통해 저장할 공간을 만들어 준 것.
	
	ex_arr[0] = new Example();
			// 여기에는 Example 클래스 뿐만 아니라 
			// Inter_example이 구현되어 있는 모든 클래스가 다 들어올 수 있다. 

} // end of main

4) 인터페이스와 추상클래스의 차이점

  • 추상클래스는 메소드 중에 추상 메소드(미완성 메소드)가 있어서 추상 클래스가 된 경우를 말하지만, 인터페이스는 속해있는 모든 메소드가 미완성 메소드이다.

5) Interface의 다중상속

  • 인터페이스는 클래스와 달리 다른 인터페이스를 여러 개 상속 받아오는 다중 상속이 가능하다.
  • 인터페이스를 다중 상속 받아온 클래스는 상속 받아온 인터페이스에 있는 모든 메소드를 다 Overriding 해주어야 한다.

  • 인터페이스-인터페이스 간의 다중 상속 O
  • 클래스에서 여러 인터페이스 다중 구현 O
  • 다중상속 받은 인터페이스를 클래스에 구현하는 것 O

3. Exception(예외처리)

1) ArrayIndexOutOfBoundsException

  • 배열의 크기가 오버되어지면 발생하는 exception

2) ArithmeticException

  • 분모에 0 이 들어가는 경우에 발생하는 exception

3) 예외처리 여러번 하기

public static void main(String[] args) {
	
	// 방법1
	int[] num_arr = {10,20,30};
	
	for(int i=3; i>=0; i--) { 
		
		try {
			int val = num_arr[i]/i;
			System.out.println(val);
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println(">> 배열의 인덱스 범위가 초과되었습니다. <<");
		} catch (ArithmeticException e) {
			System.out.println(">> 분모에는 0 이 올 수 없습니다. <<\n"); 
		}
		
	} // end of for
	
	///////////////////////////////////////////
	
	// 방법2
	int[] num2_arr = {10,20,30};
	
	for(int i=3; i>=0; i--) { 	
		
		try {
			int val = num2_arr[i]/i;
			System.out.println(val);
			
		} catch (ArrayIndexOutOfBoundsException | ArithmeticException e) {
			e.printStackTrace();
		} 
		
	} // end of for

} // end of main

4) Exception 클래스

public static void main(String[] args) {
	
	String[] str_arr = {"10","스물","30"};
	
	for(int i=3; i>=0; i--) { 	// 3,2,1,0 4번 반복
		
		try {
			int val = Integer.parseInt(str_arr[i])/i; 		
            // 문자열을 숫자로 돌려서 나누기 
			System.out.println(val);
		} catch (ArrayIndexOutOfBoundsException e) { 	
        // 만약 ArrayIndexOutOfBoundsException 이 오류라면 여기
			System.out.println(">> 배열의 인덱스 범위가 초과되었습니다. <<");
		} catch (ArithmeticException e) {	
        // 만약 ArithmeticException 이 오류라면 여기
			System.out.println(">> 분모에는 0 이 올 수 없습니다. <<\n"); 
		} catch(Exception e) {		
		// 나머지 모든 오류라면 여기(if-else문 같은 느낌)
		// Exception은 나머지 모든 오류를 다 받기 때문에 가장 마지막에 와야한다.
			System.out.println("오류 메시지 : " + e.getMessage());
		}
		
	} // end of for

} // end of main
  • Exception은 Exception들 중에 부모클래스로 모든 예외처리를 다 포함하고 있기 때문에 위로 올라가면 그 밑의 예외처리들은 도달할 수 없는 코드가 되어버린다.

5) finally

public static void main(String[] args) {
	
	String[] str_num_arr = {"10","20","삼십","40"};
	
	int count = 0;
	
	for( String str : str_num_arr) {
	
		try {
			System.out.println(Integer.parseInt(str));
		} catch(Exception e) { 		// 오류가 나게 되면 catch에서 받음 			
			System.out.println(str+"(은)는 숫자로 변경이 불가합니다.");
		} finally {
			// finally는 위에서 오류가 발생하든지 
            // 또는 위에서 오류가 발생하지 않든지 관계없이 
			// 무조건 실행해야 하는 것들은 finally 속에 기술해주면 된다. 
			System.out.println(++count 
            + "번 반복 >> 여기는 오류가 발생하든 발생하지 않든 실행되어야 합니다. << \n");
		}
		
	} // end of for

} // end of main

6) 에러 메시지

e.getMessage() : 오류 메시지를 알려주는 것
e.printStackTrace() : 어디가 오류인지 모여주는 것

7) 사용자(개발자)가 정의하는 예외(exception)절 클래스

  • Exception 클래스를 상속 받아온 다음, 생성자 내에서 예외메시지(오류메시지) 등록
  • Exception 클래스
public class Example_exception extends Exception {

	private static final long serialVersionUID = 1L;

		// 기본 생성자
		public Example_exception() {
		  // super(" 하고싶은 말 작성(이게 오류 메시지) "); 	
          // 부모클래스의 생성자 super();
			super(">> 5보다 작은 수는 입력 불가능 합니다. <<\n"); 
		}
		
		
		// 파라미터가 있는 생성자
		public Example_exception(String err_msg) {
			super(err_msg); 	
            // 다른 클래스에서 호출해서 에러 메시지를 내가 하고싶은 대로 적을 수 있다.  
		}
	
} // end of class
  • 예시 클래스
public class Example {
	
	// field
	int input_number;

	// method
	// getter-setter
	public int getNumber() {
		return input_number;
	}

	public void setNumber(int number) {
		this.input_number = number;
	}
	
	
	// 받아온 숫자를 출력해주는 메소드
	public void num_info() {
		System.out.println("입력한 숫자 : " + input_number);
	}

	
	// 5보다 큰 값만 받아와야하는 메소드 1
	public void num_five(int input_num) throws Example_exception {
										// num_five라는 메소드를 실행했을 때 
                                        // 5보다 작은 값이 들어오게 되면 오류를 출력
		if(input_num < 5) {
			throw new Example_exception();
			// 만일 input_num의 값이 5보다 작다면 Example_exception 실행시킨다.
			// 그래서 객체를 하나 만들어서 만일 input_num의 값이 5보다 작다면
			// Example_exception 예외를 던지게 된다. 
		} else {
			System.out.println("입력한 값은 " + input_num + "입니다. \n");
		}
		
	} // end of void num_five
	
	
	// 5보다 큰 값만 받아와야하는 메소드 2
	public void num_five2(int input_num) throws Example_exception {
								
		if(input_num < 5) {
			throw new Example_exception("5보다 작은 수인 "+ input_num + "은 입력이 안된다!!!!!!!");
			// Example_exception 클래스의 파라미터가 있는 생성자를 받아온 것.
		} else {
			System.out.println("입력한 값은 " + input_num + "입니다. \n");
		}
		
	} // end of void num_five	
	
	
	// 입력한 값을 보여주면서 5보다 큰 값만 받아와야하는 메소드
	public void num_info_five(int input_num) throws Example_exception {
		
		num_five2(input_num); 
		// throws Example_exception를 적어주기 전에는 에러가 발생함
		// 현재 클래스에서 try-catch로 에러를 해결해주어도 괜찮으나, 
		// 'add throws declaration'을 눌러서 throws Example_exception 추가해주면
		// 메인 클래스에서 에러 메시지 작성을 할 수 있게 된다. 
		
		num_info();
		
	}
}
  • 메인 클래스
public static void main(String[] args) {
	
	Example ex = new Example();
	
	ex.input_number = 3;
	ex.num_info();
	// 입력한 숫자 : 3
	
	// 5보다 큰 값만 받아와야하는 메소드 1 출력
	try {
		ex.num_five(ex.input_number);
	} catch (Example_exception e) {
		System.out.println("오류메시지 : " + e.getMessage());
		//오류메시지 : >> 5보다 작은 수는 입력 불가능 합니다. <<
	}
	
	// 5보다 큰 값만 받아와야하는 메소드 2 출력
	try {
		ex.num_five2(ex.input_number);
	} catch (Example_exception e) {
		System.out.println("오류메시지 : " + e.getMessage());
		// 오류메시지 : 5보다 작은 수인 4은 입력이 안된다!!!!!!!
	}
	
	// 입력한 값을 보여주면서 5보다 큰 값만 받아와야하는 메소드 출력
	try {
		ex.num_info_five(ex.input_number);
	} catch (Example_exception e) {
		System.out.println(ex.input_number + "(은)는 5보다 작은 수이니 다시 입력하세요. \n"); 
		// Example 클래스에서 메인클래스로 넘긴 예외 메시지를 여기서 입력해줄 수 있음. 
        // 입력한 숫자 : 3
		// 3(은)는 5보다 작은 수이니 다시 입력하세요. 
	}

} // end of main

사용자(개발자)가 정의하는 예외(exception)절 클래스 여기는 내가 간략하게 정리하느라고 만들어낸 코드라서 오류 있을지도 모름... 허허....

profile
이런 저런 기록들

0개의 댓글