인터페이스
인터페이스 정의 방법
public interface A{
public static final int num = 999;
public abstract int add(int a, int b);
}
인터페이스를 정의하기 위해선 일반 클래스 에서 정의하던 것에서 class를 interface로 바꾸어 주면 된다.
단, 내부의 필드는 public static final, 메서드는 public abstract 으로 지정해 주어야 된다.
모든 인터페이스에 적용이 되어야 하므로 생략이 가능하다.
인터페이스 구현
public class AA implements A{
@override
public int add(int a, int b){
return a+b;
}
}
인터페이스를 가져와 사용하기 위해선 implements 키워드를 사용하여 해당하는 인터페이스를 사용할 수 있다. 물론 여러 개 가져와 사용도 가능하다.
해당 인터페이스를 가져왔다면, 그에 따른 추상 메소드를 모두 구현해야한다.
그렇게 하지 않는다면 클래스를 추상 클래스로 만들어야된다.
인터페이스 타입으로 객체 생성
public class AA implements A{
public void minus(int a, int b){
return a-b;
}
@override
public int add(int a, int b){
return a+b;
}
}
public static void main(String[] args){
AA aa = new A(); //인터페이스로 객체 생성
aa.add(1,2); // 호출 가능
aa.minus(3,1); // 호출 불가
}
인터페이스로 객체 생성을 한다면 기존 클래스에 있는 메소드는 사용할 수 없다.
인터페이스간 상속
public interface A{
public static final int num = 999;
public abstract int add(int a, int b);
}
public interface B extends A{
public static final int b;
}
인터페이스 간에도 상속이 가능하다.
인터페이스 기본 메소드
인터페이스의 메소드는 원래는 선언만 가능하여 구현할 수 없었지만, Java 8 이후부터 메서드가 구현부를 가질 수 있도록 하였다.
public interface Test{
public static final int num = 999;
int minus(int a, int b);
default void Hello1(){
System.out.println("Hello!");
Bye();
}
default void Hello2(){
System.out.println("Hello!");
Bye();
}
static int add(int a, int b){
return a+b; // 메인 함수에서 바로 호출 가능
}
private void Bye(){
System.out.println("Bye");
}
}
public class A implements Test{
public int minus(int a, int b){
return a-b;
}
public void Hello1(){
System.out.println("hello?"); // 상속받은 클래스에서 재정의 가능
}
}
public static void main(String[] args){
A a = new A();
a.Hello1(); // hello? 출력
Test.add(3,4) // 7 출력
Test.Hello() // 호출 불가
a.Hello2(); // 인터페이스에 있는 메소드 실행
}
| 메서드 | 설명 |
|---|---|
| default | 상속받은 클래스에서 무조건 구현하지 않아도 된다. |
| static | 객체를 생성하지 않고 바로 사용할 수 있다. |
| private | 인터페이스 내에서만 사용이 가능하다. |
| private static | 인터페이스 내에서도 static, private static 메서드만 호출이 가능하다. |
예외 처리
Java의 예외 처리 방법
public static void divide(int a, int b) throws ArithmeticException{
if(b == 0){
throw new ArithemticEception("0으로 나눌 수 없습니다.")
}
return a/b;
}
public static void main(String[] args){
try{
File f = new File("aaa.txt");
FileReader freader = new FileReader(f);
int a = 10;
int b = 0;
divide(a,b);
}
catch(ArithmeticException e){ // 0으로 나누었을 때 예외처리
e.getMessage();
e.printStackTrace();
}
catch(FileNotFoundException e){ // 파일을 찾을 수 없을 때 예외처리
System.out.println(e);
}
catch(Exception e){ // 그 이외에 나오는 예외 처리
System.out.println(e);
}
finally{ // 무조건 마지막에 실행됨
freader.close()
}
}
Java에서 예외 처리에는 try catch 문이 있다.
catch 에서도 맨 위에 있는 catch문이 먼저 작동되므로 상위 예외 처리를 위에다 올려놓으면 어떤 예외가 발생했는지 알기 힘들 수 있다.
파일을 열었을 때처럼 제때 닫아주어야 하는 경우에 예외가 나게 된다면 finally 키워드를 사용하여 예외가 발생했더라도 무조건 실행이 가능하도록 만들어 줄 수 있다.
Throw는 java에서 제공하는 예외를 개발자가 강제로 발생 시킬 수 있게 만들고
Throws는 해당 메서드 내에서 예외처리를 하는 것이 아닌 메서드 사용한 곳에서 예외 처리를 하도록 전가하는 것이다.
자바의 예외 계층 구조

Exception과 Error의 차이
Exception은 프로그램 실행 중 발생하는 에러고 프로그램에서 복구할 수 있는 장애를 말한다.
Error는 실제 실행 중 비정상적인 동작을 말하는 것이고, 프로그램이 복구할 수 없기 때문에 프로그램은 비정상적으로 종료된다. 예시로 OutOfMemory, StactOverFlow, ThreadDeath 등 존재한다.
RuntimeException과 RE가 아닌 것의 차이
| checked Exception | unchecked Exception | |
|---|---|---|
| 예외 처리 | 반드시 예외를 처리해야됨 | 명시적으로 예외처리를 안해도 된다. |
| 확인 시점 | 컴파일 시점 | 런타임 시점 |
| 트랜잭션 처리 | rollback 하지 않음 | 예외 발생시 롤백 |
| 발생 원인 | 프로그램 외부 | 프로그램 내부 |
| 예시 | FileNotFoundException | ArithmeticException |
커스텀 예외
public class myException extends Exception{
public myException(String msg){
super(msg);
}
}
public class A{
private int num
public void comp(int num2){
if(num < num2){
throw new myException("더 작은 숫자를 입력하주세요") // 내가 만든 예외 사용
}
}
}
나만의 예외를 만들어서 숫자를 비교할 떄 기존 숫자보다 큰 숫자가 들어올 시 예외를 발생할 수 있도록 설정하였다.
'Java' 카테고리의 다른 글
| Java Study 6-1주차 (1) | 2023.11.11 |
|---|---|
| Java Study 5-2주차 (0) | 2023.11.05 |
| Java Study 4주차 (1) | 2023.10.29 |
| Java Study 3-2주차 (0) | 2023.10.14 |
| Java Study 3-1주차 (1) | 2023.10.14 |