JAVA/JAVA수업

#12. 추상클래스, 인터페이스, 예외처리

열하나요 2023. 7. 18. 14:51

12-1. 추상클래스

추상메소드를 선언하는 순간 추상클래스로 정의해야한다.

객체 생성이 불가능하다. 부모클래스의 역할은 가능(다형성 적용 가능)하다.

=> 기술적으로 개발자가 판단했을 때 이 클래스로는 객체 생성이 불가능해야한다 라고 생각이 들면 추상클래스로 선언 가능

=> 개녕적으로 개발자가 판단했을 때 해당 클래스가 아직 구체적으로 완벽하게 구현되지 않은 상태인 것 같다 라는 생각이 들면 추상클래스로 선언 가능

식별자앞에 abstract를 붙인다.

public abstract class Sports {

추상메소드는 Override하여 사용할 수 있다.

추상클래스는 부모클래스로 자식클래스 객체를 생성할 수 있다.

 

 

12-2. 인터페이스

인터페이스는 interface를 생성시에 만들 수 있다.

인터페이스를 쓰려면 클래스 이름 뒤에 'implements 클래스이름'을 붙인다.

public class Bossam extends Pork implements PorkI, PorkI2 {

인터페이스의 필드는 "무조건" 상수필드!!

인터페이스의 메소드는 "무조건" 추상 메소드!!

인터페이스는 다중상속을 허용한다.

 

그렇다면 추상클래스와 인터페이스는 어떻게 다른가.

 = 존재하는 목적이 다르다.
 추상클래스는 추상클래스를 상속받아서 필드, 메소드를 재사용하고 클래스를 확장하기 위한 용도이고,
 인터페이스는 클래스의 기능(메소드)구현을 강제할 용도로 사용한다.

 

12-3. 예외처리

에러(error)

시스템 에러 : 컴퓨터의 오작동으로 인해 발생하는 에러

컴파일 에러 : 프로그램 실행 전 소스코드 상의 문법적인 문제로 발생하는 에러

런타임 에러 : 프로그램 실행 중 발생하는 에러 소스코드상 문법적인 문제는 없는데 발생!!!

로지컬 에러 : 소스코드상 문법적인 문제도 없고, 실행했을 때도 굳이 문제가 발생하진 않지만 프로그램 의도상 맞지 않는 것

 

예외 : 시스템 에러는 제외한 나머지 컴파일, 런타임, 논리에러와 같이 비교적 덜 심각한 에러들 (주로 런타임에러)

 

예외처리

예측가능한 에러를 예외처리 해준다.

1. try ~ catch 구문이용
2. throws구문을 이용해서 떠넘긴다.

 

#UncheckedException

RuntimeExceptiom : 프로그램 실행 시 발생되는 예외들

RuntimeException의 자식클래스들

 

1. NullPointerException : 주소값 객체를 참조했더니 null이 들어있을 경우 발생하는 예외

2. ArrayindexOutOfBoundsException : 배열의 부적절한 인덱스로 접근할 때 발생하는 예외

3. ClassCastException : 허용할 수 없는 형변환을 진행할 경우 발생하는 예외

4. ArithmeticException : 나누기 연산을 0으로 나누면 발생하는 예외

5. NagativeArraySizeException : 배열 크기를 음수로 지정할 경우 발생하는 예외 

 

"사용자에게 두 개의 정수값을 입력받아서 나눗셈 결과를 출력한다면" (4번 에러가 발생할 수 있다.)

public void method1() {

    Scanner sc = new Scanner(System.in);
    int num1 = sc.nextInt();
    int num2 = sc.nextInt();
	
    try {
    	System.out.println("나눗셈 결과 : " + (num1/num2));
    } catch(ArithmeticException e) {
    	e.printStackTrace();
    }    
}

try { 예외가 발생할법한 구문 } catch(발생할예외클래스이름 변수명) { 예외가 발생했을 때 실행할 구문}

printStackTrace(); 는 오류를 추적해주는 메소드이다. 개발단계나 테스트단계에서만 사용한다!

 

catch할 예외가 여러개일 경우에 다중으로 사용도 가능하다.

"사용자에게 배열의 크기를 입력받아서 크기만큼의 배열을 만들어, 100번째 인덱스 값을 출력한다면"

(2번, 5번 에러가 발생할 수 있다.)

public void method2() {
	Scanner sc = new Scanner(System.in);
    int size = 0;
    int[] arr = null;
    
    try {
    	size = sc.nextInt();
        arr = new int[size];
        System.out.println(arr[100]);
    } catch(InputMismatchException e) {
    	System.out.println("정수를 입력해주세요");
    } catch(NegativeArraySizeException e) {
    	System.out.println("0보다 큰 수를 입력해주세요"); 
    } catch(ArrayIndexOutOfBoundsException e) {
    	System.out.println("배열의 크기가 너무 작아요");
    }
}

여기서 NegativeArraySizeException과 ArrayIndexOutOfBoundsException은 RuntimeException의 자식클래스이므로 묶어서 작성할 수도 있다.

	catch(RuntimeException e) {
    	System.out.println("오류가 생겼습니다.");
    }

다중 catch문 작성 시 범위가 작은 자식타입의 예외클래스부터 먼저 기술해야한다.

 

#CheckedException

예측가능한 예외는 반드시 문법적으로 예외처리를 해줘야 한다. (주로 외부 매체 입/출력 시 발생)

방법 1. try ~ catch문으로 처리

public void method3() {
	System.out.println("아무 문자열이나 입력해주세요 > ");
    
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String str = "";
    
    try {
    	str = br.readLine();
    } catch(IOException e) {
    	e.printStackTrace();
    }
    System.out.println("문자열의 길이 : " + str.length());
}

(BufferedReader 는 Scanner와 비슷하다.)

 

다른 방법으로 예외처리를 해줄 수 있다.

방법 2. throws : 지금 여기(method())에서 말고 이 메소드를 호출한 곳에서 예외를 위임해서 처리하게끔 하겠다.

public void method4() throws IOException {
	System.out.println("아무 문자열이나 입력해주세요 > ");
    
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String str = "";
    str = br.readLine();
    System.out.println("문자열의 길이 : " + str.length());
}


public static void main(String[] args) {
	try {
    	method4();
    } catch(IOException e) {
    	e.printStackTrace();
    }
}

main 에서 예외를 위임해서 처리한다.