자바(JAVA)/미니 프로젝트 & 기초 공부

Java 기초 다시 공부하기 7주차 - 인터페이스, 내부클래스/익명클래스, 입출력, 예외 처리, 컬렉션 프레임워크

개발학생 2024. 8. 22. 17:59
반응형

1. 인터페이스

  • 다중 상속처럼 사용할 수 있는 기능
  • 추상 메서드와 상수만으로 이루어짐
접근제어자 interface 인터페이스이름 {
	public static final 타입 상수이름 = 값;
	public abstract 반환타입 메서드이름(매개변수);
	...
}

class 클래스이름 implements 인터페이스이름 {
	...
}

1) 상속과 인터페이스 동시 사용

  • 동시 사용으로 다중 상속과 같은 효과
접근제어자 interface 인터페이스이름 {
	...
}

접근제어자 class 클래스이름 {
	...
}

class 클래스이름 extends 클래스이름 implements 인터페이스이름 {
	...
}

2) 예제 실습

// Java 기초 - 인터페이스

// School 인터페이스
interface School {
    public static final int MAX_CLASS = 20;
    public static final int MAX_PERSON_PER_CLASS = 40;
    public abstract void printSchool();
}

// Students 클래스 - School 인터페이스 이용
class Students implements School {
    public void printSchool() {
        System.out.println("00 University");
    }
}

// People 클래스
class People {
    public String name;

    public void printName() { System.out.println("Name: " + name); }
}

// Students2 클래스 - People 상속, School 인터페이스 이용
class Students2 extends People implements School {
    Students2(String name) {
        super.name = name;
    }
    public void printSchool() {
        System.out.println("11 University");
    }
}

public class Interface {
    public static void main(String[] args) {
        // 1. 인터페이스 기본 사용
        System.out.println("=== 기본 인터페이스 ===");
        Students s1 = new Students();
        s1.printSchool();
        System.out.println(s1.MAX_CLASS);
        System.out.println(s1.MAX_PERSON_PER_CLASS);

        // 2. 다중 상속처럼 사용하기
        System.out.println(("=== Like 다중 상속 ==="));
        Students2 s2 = new Students2("A");
        s2.printSchool();
        s2.printName();
    }
}

2. 내부클래스/익명클래스

1) 내부 클래스(Inner Class)

(1) 특징

  • 내부 클래스에서 외부 클래스 멤버에 접근가능
  • 외부에서는 내부 클래스에 접근 불가
  • 클래스 in 클래스(클래스 안에 선언한 클래스)
class Outer {
	...
	class Inner {
		...
	}
}

(2) 종류

  • 인스턴스 클래스(instance class)
  • 정적 클래스(static class)
  • 지역 클래스(local class)
  • 익명 클래스(anonymous class)

2) 익명 클래스 (Anonymous Class)

  • 이름을 갖지 않는 클래스
  • 선언과 동시에 객체 생성
  • 일회용 클래스
클래스이름 참조변수이름 = new 클래스이름 () {
	...
}

3) 예제 실습

// Java 기초 - 내부 클래스

// 내부 클래스 구조
class Outer1 {
    public void print() {
        System.out.println("Outer1.print");
    }

    class Inner1 {
        public void innerPrint() {
            Outer1.this.print();
        }
    }

    static class InnerStaticClass {
        void innerPrint() {
//            Outer1.this.print();    // 오류 발생
        }
    }
}
abstract class People2 {
    public abstract void printInfo();
}

class Students3 extends Person {
    public void printInfo() {
        System.out.println("Student.printInfo");
    };
}

public class InnerClass {
    public static void main(String[] args) {
        // 외부 클래스
        Outer1 o1 = new Outer1();

        // 내부 클래스 - 인스턴스
        Outer1.Inner1 i1 = new Outer1().new Inner1();

        // 내부 클래스 - 정적
        Outer1.InnerStaticClass is1 = new Outer1.InnerStaticClass();

        // 익명 클래스
        Person p1 = new Person() {
            @Override
            public void printInfo() {
                System.out.println("InnerClass.printInfo");
            }
        };
    }
}

 

3. 입출력

1) 콘솔 입력/출력

System.in.read()
InputStreamReader reader = ...
BufferedReader br = ...
Scanner ...

 

System.out.println(...);
System.out.print(...);
System.out.printf(...);

* 콘솔 입출력 예제 실습

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

public class ConsoleInOut {
    // 잘 안 쓰지만 알고있으면 도움됨
    public static void referInputStream() throws IOException {
        // System.in - 엔터키까지 포함해서 데이터 읽어옴
//        System.out.println("== System.in ==");
//        System.out.print("입력: ");
//        int a = System.in.read() - '0';
//        System.out.println("a = " + a);
//        // 이 줄이 있고 없고의 차이가 있음 - 엔터키 미포함
//        System.in.read(new byte[System.in.available()]);
//
//        // InputStreamReader - 읽고자 하는 개수만큼 배열을 만들고 나서 읽어야 함
//        System.out.println("=== InputStreamReader ===");
//        InputStreamReader reader = new InputStreamReader(System.in);
//        char[] c = new char[3];
//        System.out.print("입력: ");
//        reader.read(c);
//        System.out.println(c);

        // BufferedReader - 원하는 개수만큼 읽을 수 있음
        System.out.println("=== BufferedReader ===");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.print("입력: ");
        String s1 = br.readLine();
        System.out.println("s1 = s1");
    }

    public static void main(String[] args) throws IOException {
        // 1. 입력
        // 1-1. 다른 입력 방식 참고
//        referInputStream();

        // 1-2. Scanner
        System.out.println("=== Scanner ===");
        Scanner sc = new Scanner(System.in);
//        System.out.print("입력1: ");
//        System.out.println(sc.next());
//        sc.nextLine();
//
//        System.out.println(("입력2(int 아닌 값 입력 시 오류): "));
//        System.out.println(sc.nextInt());
//        sc.nextLine();

        // 가장 많이 사용하는 방법: BufferedReader처럼 자유롭게 사용 가능
        System.out.print("입력3: ");
        System.out.println(sc.nextLine());

        // 참고: 문자열-정수, 정수-문자열 간 변환 방법(자주 쓰임)
        int num = Integer.parseInt("12345");
        String str = Integer.toString(12345);

        // 2. 출력
        System.out.println("=== 출력 ===");
        System.out.println("Hello");
        System.out.println("World!");

        System.out.print("Hello");
        System.out.print("World!");
        System.out.println();

        System.out.printf("Hello");
        System.out.printf("World!");
        System.out.println();

        String s = "자바";
        int number = 3;

        System.out.println(s + "는 언어 선호도 " + number + "위 입니다.");

        // 여기부터 문자열 포맷하여 출력
        System.out.printf("%s는 언어 선호도 %d위 입니다.\\n", s, number);     // 포맷

        System.out.printf("%d\\n", 10);    //10진수
        System.out.printf("%o\\n", 10);    //8진수
        System.out.printf("%x\\n", 10);    //16진수

        System.out.printf("%f\\n", 5.2f);     //실수

        System.out.printf("%c\\n", 'A');    //문자(char)
        System.out.printf("%s\\n", "안녕하세요");    //문자열(String)

        // 정수 자릿수 표현(5d이므로 5자리)
        System.out.printf("%-5d\\n", 123);    // 왼쪽 정렬
        System.out.printf("%5d\\n", 1234);    // 오른쪽 정렬
        System.out.printf("%5d\\n", 12345);    // 오른쪽 정렬2

        // 실수 자릿수 표현(반올림)
        System.out.printf("%.2f\\n", 1.12645123f);
    }
}

 

*(System.in에서)파란색 표시 부분 코드에 주석을 쓰면 엔터값이 포함되어 숫자값이 제대로 출력 안 됨

2) 파일 입출력

(1) 파일 입력(읽기)

  • 파일로부터 입력받음
BufferedReader ...

(2) 파일 출력(쓰기)

  • 파일로 출력
FileWriter ...
PrintWriter ...

* 파일 입출력 예제 실습

import java.io.*;

public class FileInOut {
    public static void main(String[] args) throws IOException {
        // 1. 파일 쓰기
        FileWriter fw = new FileWriter("./memo.txt");
        String memo = "헤드라인\\n";
        fw.write(memo);

        memo = "1월 1일 날씨 맑음\\n";
        fw.write(memo);

        fw.close();

        PrintWriter pw = new PrintWriter("./memo.txt");
        memo = "헤드 라인";
        pw.println(memo);

        memo = "1월 1일 날씨 맑음";
        pw.println(memo);

        pw.close();

        // 2. 파일 이어 쓰기
        FileWriter fw2 = new FileWriter("./memo.txt",true);

        memo = "1월 2일 날씨 완전 맑음\\n";
        fw2.write(memo);
        fw2.close();

        PrintWriter pw2 = new PrintWriter(new FileWriter("./memo.txt",true));

        memo = "1월 3일 날씨 또 맑음!";
        pw2.println(memo);
        pw2.close();

        // 3. 파일 입력
        BufferedReader br = new BufferedReader(new FileReader("./memo.txt"));

        while (true) {
            String line = br.readLine();

            if (line == null) {
                break;
            }

            System.out.println(line);
        }
        br.close();

    }
}

4. 예외 처리

1) 예외(Exception) - 정상적이지 않은 Case

  • 0으로 나누기

  • 배열의 인덱스 초과
  • 없는 파일 열기

2) 예외 처리(Exception Handling)

  • 정상적이지 않은 Case에 대한 적절한 처리 방법
try {
	...
} catch (예외 case 1) {
	...
} catch (예외 case 2) {
	...
}
int a = 0;

try {
	a = 5 / 0;
} catch (ArithmeticException e) {
	System.out.println(e);
} 

3) finally

  • 예외 발생 여부와 관계없이 항상 실행되는 부분
try {
	예외가 발생할 수도 있는 부분;
} catch (예외 case 1) {
	예외 case 1이 발생해야 실행되는 부분;
} finally {
	항상 실행되는 부분;
}

4) throw, throws

  • throw: 예외를 발생 시킴
  • throws: 예외를 전가 시킴
... 함수이름() {
	throw new Ecxception();
}

... 함수이름() throws Exception {
	...
}

* 예제 실습

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

class NotTenException extends RuntimeException {}

public class ExceptionPro {

    private static boolean checkTen(int ten) {
        if (ten != 10) {
            return false;
        }
        return true;
    }
    public static boolean checkTenWithException(int ten) {
        try {
            if (ten != 10) {
                throw new NotTenException();
            }
        } catch (NotTenException e) {
            System.out.println("e = " + e);
            return false;
        }

        return true;
    }
    public static boolean checkTenWithThrows(int ten) throws NotTenException {
        if (ten != 10){
            throw new NotTenException();
        }
        return true;
    }

    public static void main(String[] args) throws IOException {
        // 1. 예외
        // 1-1. 0으로 나누기
        System.out.println("=== 0으로 나누기 ===");
//        int a = 5 / 0;

        try {
            int a = 5 / 0;
        } catch (ArithmeticException e) {
            System.out.println("0으로 나누기 예외 발생");
            System.out.println("e = " + e);
        } finally {
            System.out.println("1-1 연습 종료");
        }

        // 1-2. 배열 인덱스 초과
        System.out.println("=== 배열 인덱스 초과 ===");
        int[] b = new int[4];
//        b[4] = 1;

        try {
            b[4] = 1;
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("e = " + e);
        }

        // 1-3. 없는 파일 열기
        System.out.println("=== 없는 파일 열기 ===");
//        BufferedReader br = new BufferedReader(new FileReader(("abc.txt")));

        // 2. throw, throws
        System.out.println("=== checkTen ===");
        boolean checkResult = ExceptionPro.checkTen(9);
        System.out.println("checkResult = " + checkResult);

        System.out.println("=== checkTenWithException ===");
        checkResult = ExceptionPro.checkTenWithException(9);
        System.out.println("checkResult = " + checkResult);

        System.out.println("=== checkTenWithThrows ===");
        try {
            checkResult = checkTenWithThrows(5);
        } catch (NotTenException e) {
            System.out.println("e = " + e);
        }
        System.out.println("checkResult = " + checkResult);
    }

}

5. 컬렉션 프레임워크(Collection Framework)

  • 여러 데이터를 편리하게 관리할 수 있게 만들어 놓은 것 → 자료구조 및 알고리즘을 구조화
  • 대표 인터페이스: List, Set, Map

1) List 인터페이스

  • 순서가 있는 데이터의 집합
  • 데이터 중복 허용
  • 대표 구현 클래스
    • ArrayList
    • LinkedList
    • Vector
ArrayList list1 = new ArrayList();
LinkedList list2 = new LinkedList();
Vector v = new Vector();

2) Set 인터페이스

  • 순서가 없는 데이터의 집합
  • 데이터 중복 허용 x
  • 대표 구현 클래스
    • HashSet
    • TreeSet
HashSet set1 = new HashSet();
TreeSet set2 = new TreeSet();

3) Map 인터페이스

  • 키와 값의 쌍으로 이루어진 데이터 집합: 순서를 유지하지 않음
  • 데이터 중복 허용
  • 대표 구현 클래스
    • HashMap
    • TreeMap
HashMap map1 = new HashMap();
Treemap map2 = new TreeMap();

* 예제 실습

import jdk.internal.org.objectweb.asm.Handle;

import java.util.*;

public class CollectionFw {
    public static void main(String[] args) {
        // 1. List
        // 1-1. ArrayList
        ArrayList list1 = new ArrayList();
        list1.add(1);
        list1.add(2);
        list1.add(3);
        System.out.println("list1 = " + list1);

        list1.add(0, 10);
        System.out.println("list1 = " + list1);
        System.out.println("list1.size() = " + list1.size());
        System.out.println("list1.contains(1) = " + list1.contains(1));
        System.out.println("list1.indexOf(10) = " + list1.indexOf(10));

        // 1-2. LinkedList
        System.out.println("=== LinkedList ===");
        LinkedList list2 = new LinkedList();
        list2.add(1);
        list2.add(2);
        list2.add(3);
        System.out.println("list2 = " + list2);

        list2.addFirst(10);
        list2.addLast(20);
        System.out.println("list2 = " + list2);
        list2.remove(Integer.valueOf(1));
        System.out.println("list2 = " + list2);
        list2.removeFirst();
        list2.removeLast();
        System.out.println("list2 = " + list2);
        System.out.println("list2.size() = " + list2.size());

        // 2. Set
        // 2-1. HashSet
        System.out.println("=== HashSet ===");
        HashSet set1 = new HashSet();
        set1.add(1);
        set1.add(2);
        set1.add(3);
        System.out.println("set1 = " + set1);

        set1.remove(1);
        System.out.println("set1 = " + set1);

        set1.add(2);
        set1.add(3);
        System.out.println("set1 = " + set1);
        System.out.println(set1.size());
        System.out.println(set1.contains(2));

        // 2-2. TreeSet
        System.out.println("=== TreeSet ===");
        TreeSet set2 = new TreeSet();
        set2.add(1);
        set2.add(2);
        set2.add(3);
        System.out.println("set2 = " + set2);

        set2.remove(2);
        System.out.println("set2 = " + set2);

        set2.clear();
        System.out.println("set2 = " + set2);

        set2.add(10);
        set2.add(5);
        set2.add(15);
        set2.add(15);
        System.out.println("set2 = " + set2);
        System.out.println(set2.first());
        System.out.println(set2.last());
        System.out.println(set2.lower(10));
        System.out.println(set2.higher(10));

        // 3. Map
        // 3-1. HashMap
        System.out.println("=== HashMap ===");
        HashMap map1 = new HashMap();
        map1.put(1,"kiwi");
        map1.put(2,"apple");
        map1.put(3,"mango");

        map1.remove(2);
        System.out.println("map1 = " + map1);
        System.out.println("map1.get(1) = " + map1.get(1));

        // 3-2. TreeMap
        System.out.println("=== TreeMap ===");
        TreeMap map2 = new TreeMap();
        map2.put(10,"kiwi");
        map2.put(5,"apple");
        map2.put(15,"mango");
        System.out.println("map2 = " + map2);

        System.out.println(map2.firstEntry());
        System.out.println(map2.firstKey());
        System.out.println(map2.lastEntry());
        System.out.println(map2.lastKey());
        System.out.println(map2.lowerEntry(10));
        System.out.println(map2.higherEntry(10));
    }
}

반응형