자바(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));
}
}
반응형