인터페이스
: 추상메소드만 보관하는 특별한 클래스
=> 인터페이스를 사용하면 다형성을 적용할 수 있으며 다중상속 받은 것처럼 구현할 수 있다.
1. 인터페이스는 정의할 때 interface키워드를 이용해서 정의
2. 인터페이스는 추상메소드만 정의할 수 있다.
- 인터페이스에 정의하는 모든 메소드는 public abstract을 생략해도 된다.
- 멤버변수는 상수로 public static final이다.
- 하위클래스에서 오버라이딩하면 자동으로 public이 추가된다.
3. 클래스가 인터페이스를 상속할 때는 implements로 상속(구현)
4. 인터페이스가 인터페이스를 상속할 수 있다.
- 인터페이스가 인터페이스를 상속하는 경우 extends를 이용
5. 클래스가 인터페이스를 상속하는 경우에는 다중상속이 가능하다. 즉, 여러 개의 인터페이스를 상속할 수 있다.
- , 로 구분해서 정의
- 인터페이스가 인터페이스를 상속하는 경우에도 다중상속을 허용
6. 클래스와 인터페이스를 모두 상속하는 경우 extends가 implements보다 먼저 선언되어야 한다.
interface SuperInterfaceA{
void show(); // 인터페이스가 갖는 추상메소드
}
interface InterA extends SuperInterfaceA{
void test();
void display();
}
interface InterB{
void change();
}
interface InterC extends InterA, InterB{
// InterC 인터페이스는 show, test, display, change 다 갖고 있음
}
class SuperObj{
}
class TestA extends SuperObj implements InterA, InterB{ //6번
// InterA, InterB를 상속하면 TestA는 추상클래스가 된다 - 추상메소드를 모두 오버라이딩해야 한다.
@Override
public void show() {
}
@Override
public void change() {
}
@Override
public void test() {
}
@Override
public void display() {
}
}
public class InterfaceTest2 {
public static void main(String[] args) {
}
}
// 자세히 보기
class Parant{
}
class A extends Parant{
}
class B extends Parant{
}
class C extends Parant implements Group1{
}
class D extends Parant implements Group1{
}
interface Group1{
}
class Test{
// A,B,C,D는 Parant의 하위
public void run(Parant obj) {
}
// C,D는 Parant와 Group1을 모두 상위로 갖는다.
public void test(Group1 obj) {
}
public void exam(Group1 obj){
}
}
public class InterfaceTest {
public static void main(String[] args) {
Test test = new Test();
// 생성된 A,B,C,D객체를 메인메소드 내부에서 사용하지 않고 run메소드에서만 사용하면 참조 변수를 정의해서 사용하지 않고
// 바로 객체를 생성해서 매개변수로 전달해도 된다.
A obj = new A();
test.run(obj);
test.run(new B());
test.run(new C());
test.run(new D());
test.exam(new C());
test.exam(new D());
}
}
예외처리
try-catch
▶ 순서
1. 예외 발생
2. 해당 예외객체가 메모리에 생성됨(heap) -> 객체가 만들어져서 전달됨
3. catch블럭의 예외변수에 할당됨
4. try블럭의 실행이 멈추고 catch블럭으로 이동되어 코드가 실행됨
* try~catch
public class ExceptionTest02 {
public static void main(String[] args) {
try {
// 예외발생 가능성이 있는 코드
System.out.println("try블럭시작");
// Exception 발생하면 더 이상 try블럭안의 코드를 실행하지 않고 catch블럭으로 이동함
//System.out.println(args[0]);
System.out.println(10/0);
System.out.println("try종료");
}catch(Exception e) {
// 예외가 발생하면 처리할 문장을 구현
System.out.println("예외발생함");
}
}
}
* try~catch~catch...
=> catch블럭을 다중 선언하고 사용하는 것은 가능하나, 상위 Exception클래스보다 하위 Exception클래스를 먼저 정의해야 한다.
public class ExceptionTest03 {
public static void main(String[] args) {
Scanner key = new Scanner(System.in);
try {
// 예외발생 가능성이 있는 코드
System.out.println("시작");
System.out.println("숫자입력");
System.out.println(Integer.MAX_VALUE); //1231231232133
int num1 = key.nextInt();
System.out.println("나눌 숫자를 입력");
int num2 = key.nextInt();
System.out.println("결과=>"+(num1/num2));
System.out.println("종료");
}catch(ArithmeticException e) {
System.out.println("0으로 나눴음. 다시 입력하기");
}catch(InputMismatchException e) {
System.out.println("숫자가 아님. 다시 입력해라");
}catch(Exception e) {
System.out.println("예외발생");
System.out.println("예외메세지=>"+e.getMessage());
// 개발 시에 가장 많이 사용함 -
// 여러 클래스를 이용해서 사용하는 경우 오류를 추적해서 어떤 클레스에서 예외가 발생하는지 확인하는 것이 가능
e.printStackTrace();
}
}
}
* tryAcatch~finally
=> 예외가 발생하거나 발생하지 않거나 반드시 실행해야 하는 코드가 있는 경우 finally블럭에 정의한다.
public class ExceptionTest04 {
public static void main(String[] args) {
Scanner key = new Scanner(System.in);
try {
// 예외발생 가능성이 있는 코드
System.out.println("시작");
System.out.println("숫자입력");
System.out.println(Integer.MAX_VALUE); //1231231232133
int num1 = key.nextInt();
System.out.println("나눌 숫자를 입력");
int num2 = key.nextInt();
System.out.println("결과=>"+(num1/num2));
System.out.println("종료");
}catch(ArithmeticException e) {
System.out.println("0으로 나눴음. 다시 입력하기");
}catch(InputMismatchException e) {
System.out.println("숫자가 아님. 다시 입력해라");
}catch(Exception e) {
System.out.println("예외발생");
System.out.println("예외메세지=>"+e.getMessage());
// 개발 시에 가장 많이 사용함 -
// 여러 클래스를 이용해서 사용하는 경우 오류를 추적해서 어떤 클레스에서 예외가 발생하는지 확인하는 것이 가능
e.printStackTrace();
}finally {
System.out.println("무조건 실행되는 코드 ---------------- 자원반납");
}
}
}
예외 선언하기 throw, throws
=> 예외 떠넘기기(알리기)
- throw : 예외를 발생시키는 키워드
throws : 예외를 메서드에 선언할 때 사용
- 처리 방법
1. 예외가 발생하는 곳에서 예외에 대한 처리를 구현
2. 예외를 발생하는 곳에서 처리하지 않고 호출한 곳에서 처리
public class ThrowsExceptionTest01 {
// 1. 예외가 발생하는 곳에서 예외에 대한 처리를 구현
public void test(String fileName) {
try {
FileReader fr = new FileReader(fileName); // 에러발생코드
}catch(FileNotFoundException e) {
System.out.println("예외처리작업...완료");
}
}
// 2. 예외를 발생하는 곳에서 처리하지 않고 호출한 곳에서 처리
public void test2(String fileName) throws FileNotFoundException{
FileReader fr = new FileReader(fileName); // 에러발생코드
}
public static void main(String[] args) {
ThrowsExceptionTest01 obj = new ThrowsExceptionTest01();
//1. 예외를 예외가 발생한 메소드 내부에서 처리하고 있으므로 호출한 곳에서는 예외 발생 유무를 확인할 수 없다.
// test메소드를 A위치에서 호출함 - A클래스의 a메소드에서 호출한다 가정
obj.test("test2.txt");
// test메소드를 B위치에서 호출 - B클래스의 b메소드에서 호출한다 가정
obj.test("test2.txt");
//2. 예외를 호출한 곳(main)에서 처리
//test2메소드를 A위치에서 호출 - A클래스의 a메소드에서 호출한다 가정
try{
obj.test2("test2.txt"); //에러발생코드를 실행 => 에러발생함
}catch(FileNotFoundException e) {
System.out.println("파일명을 다시 선택하세요.=====> 선택할 수 있는 코드를 작성");
}
// test2메소드를 B위치에서 호출 - B클래스의 b메소드에서 호출한다 가정
try{
obj.test2("test2.txt");
}catch(FileNotFoundException e) {
System.out.println("test.txt로 작업할 수 있도록 파일을 정의");
}
}
}
public class MyException extends Exception{
public MyException(String msg) {
super(msg); // Exception클래스의 메세지를 전달 - Exception의 매개변수 1개 생성자를 호출
}
}
public class MyExceptionTest {
public static void main(String[] args) {
System.out.println("프로그램시작");
System.out.println("스텝1");
System.out.println("스텝2");
System.out.println("스텝3");
Scanner key = new Scanner(System.in);
System.out.println("숫자를 입력하세요");
int num = key.nextInt();
if(num%2==1) {
//홀수가 입력되어지면 예외상황으로 간주 - 예외를 인위적으로 발생시킴
try {
throw new MyException("홀수가 입력되었습니다.(error)"); //에러발생코드
}catch(Exception e) {
System.out.println("예외처리 완료");
System.out.println("----------------------");
System.out.println(e.getMessage());
}
}else {
System.out.println("정상스텝");
}
}
}
- 예외 종류
import java.io.FileReader;
import java.util.Scanner;
class Super{
}
class Sub extends Super{
}
public class ExceptionTest01 {
public static void main(String[] args) {
// 1. 개발자가 실수할 수 있는 부분-------------------------------------------------------
System.out.println("***********프로그램 시작************");
//System.out.println(10/0); //ArithmeticException
//System.out.println(args[0]); //ArrayIndexOutOfBoundsException
String str = null; // 참조변수가 null인데 메소드를 호출해서 사용하는 경우
//str.length(); // NullPointerException
Super obj = new Super();
//Sub obj1 = (Sub)obj; // 변환할 수 없는 타입으로 강제 형변환하는 경우 - ClassCastException
//2. 외부 요인이나 사용자의 실수로 예외가 발생하는 경우
Scanner key = new Scanner(System.in);
System.out.println("값을 입력하세요:");
int data = key.nextInt();
System.out.println("입력하신 데이터는=>"+data);
// 3. API에서 문법적으로 예외처리를 요구하는 경우
// RuntimeException의 하위 Exception은 문법적으로 예외에 대한 처리를 하지 않아도 되지만 해야 한다.
// 나머지 Exception은 예외처리를 하지 않으면 컴파일오류가 발생하므로 해야 한다.
FileReader fr = new FileReader("test.txt");
Integer.parseInt("100");
}
}
<예제>
문자열을 입력받아 숫자로 변환하기(에외발생 시 메세지 출력)
import java.util.Scanner;
public class ExceptionExam02 {
public static void main(String[] args) {
//필요할 경우 다음의 메서드 선언부분(메서드 시그너처)을 수정하시기 바랍니다.
ExceptionExam02 obj = new ExceptionExam02();
Scanner scan= new Scanner(System.in);
System.out.println("숫자로 변환할 문자열을 입력바랍니다.");
String str= scan.nextLine();
int result= 0;
//여기를 작성하십시오.
try {
result = convert(str);
System.out.println("변환된 숫자는 "+result+" 입니다.");
}catch(IllegalArgumentException e){
System.out.println("예외가 발생되었습니다. 문자열을 입력하지 않고 엔터를 누르셨습니다.");
e.printStackTrace();
}
}
//필요할 경우 다음의 메서드 선언부분(메서드 시그너처)을 수정하시기 바랍니다.
private static int convert(String str) throws IllegalArgumentException{ // throws IllegalArgumentException 문법적으로 쓰지 않아도 됨
// ㄴ> RuntimeException의 하위이기 때문에 쓰지 않아도 문법적으로 허용됨
int result = 0;
if(str == null || str.length() == 0){
throw new IllegalArgumentException();
}
result = Integer.parseInt(str);
return result;
}
}
'JAVA' 카테고리의 다른 글
2022-10-21 컬렉션 프레임웍 ArrayList / Vector, 스택과 큐 (0) | 2022.10.23 |
---|---|
2022-10-21 java.lang패키지와 유용한 클래스(API활용법) (0) | 2022.10.22 |
2022-10-17 객체지향언어 - 다형성. 추상클래스, 제어자 fanal (0) | 2022.10.18 |
2022-10-14 객체지향언어 - 생성자, 상속 (0) | 2022.10.17 |
2022-10-13 객체지향언어 - 배열, 클래스 메소드(static메소드)와 인스턴스 메소드 (0) | 2022.10.13 |
댓글