교육 4주 차: IntelliJ_IDEA(2)
공휴일과 휴강, 그리고 강사님 건강문제로 인한 긴급휴강으로 4주차이지만 5일 중 2일만 수업...
그래도 분량은 많다.
이걸 언제 다나갔지? 싶음ㅎ..
가능하면 매일 복습하고 정리해서 포스팅하쟈...
8장 데이터 구조 처리
8 - 1. 데이터 구조를 확장된 for문으로 처리
<확장된 for문>
for(var 변수명: 배열 및 List) {
반복하는 처리내용
}
<확장된 for문 예제>
var strs = List.of("apple", "grape", "watermelon");
for (String str : strs) {
System.out.println(str);
}
배열/리스트명.for를 입력하고 [Tap]키를 누르면 확장된 for문을 자동완성 할 수 있음.
8 - 2. Stream
- Stream: 값의 집합에 대한 처리를 사용하는 구조.(교재에 이렇게 쓰여있지만 뭔소린지..?)
<Stream 구성 예제>
var data = List.of("불닭볶음면", "짜파게티", "신라면");
var result = (int)data.stream() //Stream 소스
.filter(s -> s.length() >=4) //중간처리(값 조작)
.count(); //종단처리(값 정리)
- Stream 소스: 값의 집합으로부터 Stream을 꺼낸 것
- Stream 처리는 메소드 호출을 계속해서 작성하는 메소드 체인 형태로 사용
- 람다식 구문: 받는 값을 사용하는 변수(임의로 지정) -> 처리
- Collectors 클래스의 toList()는 ArrayList가 리턴되어 값 변경이 가능
- map메소드: 값을 처리하는 데 사용.
<map 메소드 예제>
var noodles = List.of("buldak", "zzapa", "shin");
noodles.stream().map(n -> n.toUpperCase()).toList();
<전체 처리 메소드들 예제>
noodles.stream().skip(1).toList(); //맨 처음 요소 빼고(skip) 리스트 만들기
noodles.stream().limit(2).toList(); //2개 까지만(limit) 리스트 만들기
noodles.stream().sort().toList(); //요소들 오름차순 정렬 리스트 만들기
noodles.stream().distinct().toList(); //중복 요소 생략한 리스트 만들기
- Optional: 값이 있는지 여부를 관리하는 클래스. 실제로 없는 값을 처리하려 했을 때 나타나는 버그를 줄여줌.
<Optional 예제>
var o = Optional.of("test"); //Optional에 값 설정
System.out.println(o.get()); // Optional 값 검색
System.out.println(Optional.empty().orElse("없음")); //값이 없을 때 대체값 지정하기
System.out.println(o.isPresent()); //또는 isEmpty() 값이 있는지 여부 체크.(true/false 리턴)
o.ifPresent(s-> System.out.println(s)); //값이 있을 때만 처리
8 - 3. 기본자료형의 Stream 처리
- int형, long형, double형에 대해서는 전용 Stream 클래스가 준비되어 있다. 각각 IntStream, LongStream, DoubleStream.
<IntStream 예제>
var nums = new int[]{2, 5, 3}; //int형 배열 준비
IntStream.of(nums).sum()); //IntStream 메소드로 IntStream 얻고 sum()으로 종단처리.
- 수치범위 지정해서 IntStream 생성할 때 range 메소드 사용. 인수는 시작값과 종료값을 지정하고 종료값 이전 값까지 생성. rangeClosed 메소드의 경우 종료값이 포함된 숫자열 생성.
- toArray메소드로 int형 배열을 얻을 수 있다.
- iterate 메소드는 인수의 초기값, 반복조건, 다음 값을 얻는 계산을 지정해 for문처럼 활용 가능.
- map 메소드로 값 가공, filter 메소드로 필터링, sorted 메소드로 정렬 가능.
- IntStream에서 객체의 Stream을 얻을 때는 mapToObj 메소드 사용. 반대로 객체 Stream으로부터 IntStream을 얻는 경우 mapToInt 메소드 사용
9장 메소드
9 - 1. 메소드 선언
- 메소드(Method): 실행의 단위로 Java프로그램은 메소드를 호출해 가는 것으로 처리가 진행됨.
- 메소드명은 관습적으로 소문자로 시작한다.
//메소드 선언 예제(리턴값 없음)
jshell> void msg() {System.out.println("Hello");}
//메소드 호출
jshell> msg()
//인수가 있는 메소드 선언 예제(리턴값 없음)
jshell> void greeting(String name) {System.out.println("Hello " + name);}
//인수 있는 메소드 호출
jshell> greeting("sage")
//리턴값 있는 메소드 선언
jshell> int twice(int x) {return x * 2;}
- 메소드가 복수의 인수를 받는 경우 ","로 단락을 짓는다.
- 가인수(Parameter): 메소드 선언 시 ()안에 들어가는 인수.(예제에서 String name)
- 실인수(Argument): 메소드를 호출할 때 인수로서의 값이 정해져 있는 경우(예제에서 "sage")
- 메소드가 리턴값을 돌려주는 경우 리턴값 자료형을 지정해야 하며, 리턴문을 사용해야 함.
- static 메소드 선언: 메소드 선언 전에 static을 붙인다.(예: static int twice(int x){return x * 2;})
- static 메소드는 인스턴스 생성 없이 클래스.메소드명(); 으로 호출 가능. 같은 클래스 내에서는 클래스 명을 생략하고 호출 가능.
<인스턴스 메소드 선언 예제>
public class InstanceMethodSample {
record Student(String name, int englishScore, int mathScore){
int average() {
return (this.englishScore() + this.mathScore()) / 2;
}
}
public static void main(String[] args) {
var sage = new Student("sage", 60, 80);
var a = sage.average();
System.out.println("평균점수: %d ".formatted(a));
}
}
9 - 2. 람다식 및 메소드 참조
- 람다식(Lambda): 익명 메소드라고 생각할 수 있다. 메소드 선언으로부터 메소드명과 리턴값 자료형을 제거하고 인수의 닫는 괄호")" 처리 시작의 내부 괄호 "{" 사이에 "->"를 넣는 것.
<메소드 선언을 람다식으로 나타내보기>
int twice(int x) {
return x*2;
}
//메소드 선언에서 리턴값의 자료형과 메소드명 지우기
(int x) {
return x*2;
}
//인수와 처리 사이를 ->로 연결하고 한줄로 표현
(int x) -> {return x*2;}
//처리가 1행인 경우 중괄호 생략 가능, return, 세미콜론 생략
(int x) -> x*2
//인수 자료형 생략. 인수가 1개인 경우 괄호도 생략
x -> x*2
<메소드 참조 예제>
public class MethodRefSample {
public static void main(String[] args) {
IntStream.range(0, 3)
.map(MethodRefSample::twice)
.forEach(System.out::println);
}
static int twice(int x) {
return x * 2;
}
}
/*출력결과
0
2
4
*/
- System.out.println은 메소드 참조로 대체되는 경우가 많아 "s->System.out.println(s)"는 "System.out::println"이 됨.
- IntelliJ IDEA의 기능으로 람다식을 메소드 참조로 변환할 수 있음.
9 - 3. 메소드 사용법
- 오버로드(Overloading): 인수의 조합이 다른 같은 이름의 메소드를 복수 정의하는 것.
- 메소드 체인: 메소드 호출의 결과에 대해서 메소드를 호출하는 것.
<메소드 체인 예제>
jshell> "tomato".repeat(5).length()
$4 ==> 30
//repeat메소드의 결과에 대해 length메소드를 호출
- 재귀: 메소드 안에서 그 메소드 자신을 호출하는 것. 반복문보다 다양한 형태의 반복에 대응할 수 있음.
<재귀에 의한 반복 예제>
//for (int i = 0; i < 5; i++) {System.out.println(i);} 구문을 재귀로 작성
public class Review {
public static void main(String[] args) {
loop(0);
}
static void loop(int i) {
if (i >= 5) {
return;//조건이 충족되지 않으면 return으로 if문 탈출
}
System.out.println(i);
loop(i + 1);
}
}
- 스택(Stack): 로컬 변수나 메소드의 호출 정보가 저장되는 영역.
- 스택오버플로우(StackOverflow): 스택 영역에 한계가 생겨 더이상 메소드를 호출할 수 없는 상태.
10장 입출력 및 예외
10 - 1. 파일 접근 및 예외
<파일 쓰기 예제>
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class WriteFile {
public static void main(String[] args) throws IOException {
var msg = """
test
msg
""";
var p = Path.of("test.txt"); //파일명 지정
Files.writeString(p, msg); //파일에 문자열 저장
}
}
- Files 클래스: 파일 조작에 대한 메서드 제공
메소드명 | 설명 |
String readString(Path) | 파일을 문자열로 읽음 |
Path writeString(Path, String) | 파일에 문자열 넣기 |
long size(Path) | 파일 크기 얻기 |
FileTime getLastModifiedTime(Path) | 최종 업데이트 일자 얻기 |
boolean exists(Path) | 파일이 존재 여부 확인 |
boolean isDirectory(Path) | 폴더인지 확인 |
Stream<Path> list(Path) | 파일목록 얻기 |
- Path.of 메소드는 Java 11부터 도입됐기 때문에 Java 8에서는 Path.get 메소드 사용.
<파일 읽기 예제>
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class ReadFile {
public static void main(String[] args) throws IOException {
var p = Path.of("test.txt");
String s = Files.readString(p); //파일 내용을 문자열로 읽기
System.out.println(s);
}
}
<파일 읽기 예제를 try문으로 예외처리>
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
public class ReadFile {
public static void main(String[] args) throws IOException {
try {
var p = Path.of("test.txta");
String s = Files.readString(p);
System.out.println(s);
} catch (NoSuchFileException e) {
//throw new RuntimeException(e);
System.out.println("파일을 찾을 수 없음: "+ e.getFile());
}
}
}
<try ~ catch 구문>
try{
예외가 발생할 수 있는 처리 내용
} catch (잡히는 예외1 변수) {
예외처리
} catch (잡히는 예외2 변수) {
예외처리
}
.....
- 검사 예외: 예외 처리를 꼭 해줘야 하는 예외. Exception, InterruptedException, IOException
- 비검사 예외: 예외처리가 불필요한 예외. Error, RuntimeException
10 - 2. 네트워크에서 컴퓨터 외부의 세계와 연결
- 서버: 통신이 오는 것을 기다리는 프로그램
- 클라이언트: 서버에 접속하는 프로그램
<서버 클래스 예제>
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class SimpleServer {
public static void main(String[] args) throws IOException {
var server = new ServerSocket(1599);
System.out.println("기다려주세요...");
Socket sk = server.accept();
System.out.println("연결: " + sk.getInetAddress());
InputStream is = sk.getInputStream();
System.out.println(is.read());
is.close();
sk.close();
}
}
<클라이언트 클래스 예제>
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class SimpleClient {
public static void main(String[] args) throws IOException {
var sk = new Socket("localhost", 1599);
OutputStream os = sk.getOutputStream();
os.write(123);
os.close();
sk.close();
}
}
클라이언트 클래스를 실행하고 서버 클래스로 돌아가면 실행창에 123이 표시됨.
- 소켓: 다른 프로그램과 상호작용하는 메커니즘.
- 포트번호: 하나의 컴퓨터에서 여러 개의 프로그램이 통신 대기를 수행할 수 있기 때문에 어떤 프로그램과 통신할지 식별하는 것. 65535까지 숫자로 지정할 수 있지만 1023까지는 용도가 정해져 있어 1024이후의 숫자를 지정. 같은 포트번호로 복수의 대기를 실시할 수 없다.
- OutPutStream: 데이터를 출력할 때 사용하는 클래스.
- InPutStream: 데이터를 입력할 때 사용하는 클래스.
- 프로토콜(Protocol): 송수신 내용과 순서 등을 결정한 통신교환 약정.
<TCP와 UDP>
프로토콜 | 자바클래스 | 특징 | 속도 | 용도 |
TCP | Socket,ServerSocket | 전송보증이 됨 | 느림 | 파일 전송 등 |
UDP | DatagramSocket | 이송(??) | 빠름 | 동영상 및 음성 스트리밍 |
- try-with-resource: close가 필요한 경우, 항상 close 할 수 있는 구문.
//try-with-resources 구문
try(close가 필요한 객체 변수 할당) {
처리내용
}
10 - 3. Web의 뒷면 살펴보기
- HTTP(HyperText Transfer Protocol): 웹에서 사용되는 전송 프로토콜. 현재 많은 통신이 HTTP 기반이다.
- Java에서는 문자열을 입출력하기 위해 Reader클래스와 Writer클래스가 준비되어 있다.
- HTTP요청: 클라이언트의 요청
- HTTP응답: 서버의 응답
요청 문자열 예시
pw.println("GET/index.html HTTP/1.1")
HTTP메소드 리소스 HTTP/버전
- HTTP메소드: 어떤 작업을 수행하는지를 나타냄.
HTTP메소드 | 설명 |
GET | 데이터 검색 |
POST | 데이터 보내기 |
PUT | 데이터 작성 또는 재작성 |
DELETE | 데이터 삭제 |
PUT의 경우 같은 데이터를 여러번 보내도 덮어쓰기 하기 때문에 결과적으로 동일하게 되는 경우에 사용.
- 리소스: 조작할 데이터를 나타냄
- 버전에는 1.0 또는 1.1을 지정할 수 있는데 일반적으로 1.1을 지정.
- 요청헤더: 요청에 대한 자세한 정보는 나타내는 것
요청헤더 | 설명 |
Host | 액세스 중인 도메인. 반드시 지정해야 함! |
User-Agent | 브라우저 유형 |
Referer | 링크 소스 |
HTTP 응답형식
HTTP/버전 상태코드 메시지
- 응답 헤더: 응답에 대한 자세한 정보 표시
응답헤더 | 설명 |
Content-Type | 문서유형 |
Last-Modified | 최종 변경된 날짜 및 시간 |
Content-Length | 데이터 크기 |
- 게이트웨이: TCP/IP 통신에서 서버와 클라이언트 사이의 여러 중계점.
- SSL(Secure Socket Layer): 소켓접속의 접속처가 올바른지 증명하여 통신을 암호화하는 구조.
- TLS(Transport Layer Security): SSL을 표준화한 것. SSL/TLS라고도 함.
- HTTPS: HTTP통신을 SSL/TLS로 수행하도록 한 것.
- Java에는 웹 클라이언트 라이브러리로 URLConnection과 HttpClient API가 있다.
하 이부분 너무 어려워...짜증나..복잡해...ㅋㅋㅋㅋ
교재의 많은 에제들 생략잼^^
11장 데이터 처리의 어려움
11 - 1. 반복의 어려운 단계
<문자열의 중복된 부분을 제거하는 프로그램>
public class RemoveDuplicate {
public static void main(String[] args) {
var data = "abcccbaabcc";
//계속 값을 추가해 문자열 구축
var builder = new StringBuilder();
//문자열의 길이만큼 처리 반복
for (int i = 0; i < data.length(); i++) {
//문자열의 i번째 문자검색
char ch = data.charAt(i);
//ch가 첫번째 요소가 아니면서 이전 문자와 일치하는지 확인
//&& 연산자는 첫 번째 표현식이 false면 나중 표현식 실행x, i = 0일 때 data.charAt(i - 1) 호출x.
if (i > 0 && ch == data.charAt(i - 1)) {
continue;
}
//i번째 문자가 i-1번 째 문자와 같지 않은 경우 StringBuilder객체에 문자 추가
builder.append(ch);
}
//모든 처리가 끝나면 toString메소드로 StringBuilder객체에 구축된 문자열 취득
var result = builder.toString();
System.out.println(data);
System.out.println(result);
}
}
<확장된 for문으로 예제 다시 작성>
public class RemoveDuplicate2 {
public static void main(String[] args) {
var data = "abcccbaabcc";
//앞의 문자를 기억하는 변수 prev 준비. 0 할당해 초기화
char prev = 0;
var builder = new StringBuilder();
//확장된 for문으로 작성. toCharArray메소드로 문자열 중 문자를 포함한 배열 취득.
for(char ch : data.toCharArray()) {
if(ch == prev) {
continue;
}
//같은 문자가 아닐 경우 StringBuilder객체에 추가.
builder.append(ch);
//이번 문자를 1개 이전 문자로 prev에 할당
prev = ch;
}
var result = builder.toString();
System.out.println(data);
System.out.println(result);
}
}
- 런랭스(Run-Length) 압축: 같은 데이터가 계속 될 때 데이터가 계속되는 길이를 기록하는 것에 의해 데이터를 짧게 하는 기법.
<런랭스 압축 예제>
public class RunLengthCompression {
public static void main(String[] args) {
final var COUNTER_BASE = -1;
var data = "abbcccbaaaabccccccccccccddd";
var count = COUNTER_BASE;
char prev = 0;
var builder = new StringBuilder();
for (var ch : data.toCharArray()) {
if (prev == ch) {
// 같은 문자를 붙일 떄
count++;
if (count == 9) {
builder.append('9');
count = COUNTER_BASE;
prev = 0;
}
} else {
// 다른 문자가 올때
if (count >= 0) {
// 이전 문자가 연속이므로 숫자 출력
builder.append((char) ('0' + count));
count = COUNTER_BASE;
}
builder.append(ch);
prev = ch;
}
}
// 마지막 문자가 연속이면 숫자 출력
if (count >= 0) {
builder.append((char) ('0' + count)); //0~9 사이의 int형 정수를 char로 변환하기 위해 '0' 더해줌
}
var result = builder.toString();
System.out.println(data);
System.out.println(result);
}
}
11 - 2. 상태전이와 정규식 표현
- 상태전이: 데이터에 따라 상태가 바뀌는 것. 예를 들어 쇼핑몰 시스템이라면 "주문 -> 입금대기 -> 출고 대기-> 배송완료"라는 상태 전환 시스템과 같은 것.
(?교재의 문장을 해석할 수 없다. 쇼핑몰 시스템 로직에 활용할 수 있다는 걸까..?) - 상태전이 다이어그램 예시: 주어진 문자열이 소수점이 있는 숫자 표시로 유효한지 여부를 결정짓는 프로그램.
오토마톤(Automaton): 또는 스테이트 머신. 상태가 입력에 따라 달라지는 모델
<실수판정 프로그램 예제>
public class CheckFloat {
enum FloatState {
START, INT, FRAC_START, FRAC, ZERO
}
static boolean check(String data) {
var state = FloatState.START;
for (char ch : data.toCharArray()) {
switch (state) {
case START -> { // 시작
if (ch == '0') {
state = FloatState.ZERO;
} else if (ch >= '1' && ch <= '9') {
state = FloatState.INT;
} else {
return false;
}
}
case ZERO -> { // 헤더 제로
if (ch == '.') {
state = FloatState.FRAC_START;
} else {
return false;
}
}
case INT -> { // 정수
if (ch >= '0' && ch <= '9') {
state = FloatState.INT;
} else if (ch == '.') {
state = FloatState.FRAC_START;
} else {
return false;
}
}
case FRAC_START, FRAC -> { // 소수점
if (ch >= '0' && ch <= '9') {
state = FloatState.FRAC;
} else {
return false;
}
}
}
}
return switch (state) {
case ZERO, INT, FRAC -> true;
default -> false;
};
}
public static void main(String[] args) {
System.out.println(check("")); // false
System.out.println(check("012")); // false
System.out.println(check(".12")); // false
System.out.println(check("12.")); // false
System.out.println(check("1.2.3"));// false
System.out.println(check("1..3")); // false
System.out.println(check("0")); // true
System.out.println(check("12")); // true
System.out.println(check("12.3")); // true
System.out.println(check("0.3")); // true
System.out.println(check("12.30"));// true
}
}
- enum: 프로그램 중에서 이용하는 값을 정리하여 취급할 수 있는 형.
- 정규식: 자주 필요한 처리를 미리 구조로 만들어놓은 것. Java에서 정규식을 취급하는 클래스는 java.util.regex 패키지에 정리되어 있다. 예시 프로그램의 경우 Pattern클래스와 Matcher클래스를 사용해 재기록 할 수 있다.
<Pattern 클래스와 Match 클래스 사용 예제>
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CheckFloatReEx {
static Pattern pat = Pattern.compile("(0|[1-9][0-9]*)(\\.[0-9]+)?");
static boolean check(String data) {
Matcher mat = pat.matcher(data);
return mat.matches();
}
}
<문자에 대한 정규식>
표현 | 설명 |
.(점) | 무엇이든지 한글자 |
[] | 어떤 문자, 범위 지정 가능 |
| | 어떤 표현 |
\ | 기능을 상쇄함, Java문자열에서 \\ |
() | 그룹화 |
^ | 행 앞부분 |
$ | 행 끝부분 |
<출현 횟수에 관한 정규식>
표현 | 설명 |
? | 존재하지 않습니까? |
* | 여러번 반복합니다. 없어도 가능함 |
+ | 여러번 반복합니다. 하나는 필요함 |
11 - 3. 스택과 큐
- 스택(Stack): 무엇인가를 차곡차곡 쌓은 상태를 가리키는 말. 데이터를 다루는 방법 중 하나. 가장 마지막에 쌓은 것은 가장 먼저 꺼내고(Last In First Out), 최초로 쌓은 것을 마지막에 꺼내게 됨.(First In Last Out)
- 큐(Queue): 먼저 들어간 것이 먼저 나오는 데이터 처리법.(First In First Out)
- 탐색: 데이터를 조사해 최적의 답을 찾는 것
- 깊이 우선 탐색(Depth-First Search): 분기가 있는 데이터를 처리할 때 깊은 곳까지 가는 것을 우선으로 하는 탐색법.
- 너비 우선 탐색(Breadth-First Search): 모든 분기를 처리하고 각 분기의 처리를 조금씩 깊게 하는 방법
- 깊이 우선 탐색에서는 스택을, 너비 우선 탐색에서는 큐를 사용.
- 프로그램에서는 너비 우선 탐색보다 깊이 우선 탐색을 사용하는 경우가 많다.
- Java에는 Stack 클래스가 있지만 구현형태가 오래됐고 스택을 취급하는 경우 ArrayDeque쪽이 적절하다. 선두나 말미에 추가 삭제의 성능이 좋은 데이터 구조로 양단 큐라고도 함.
예제 코드가 있는데 뭔소린지 도저히 모르겠다ㅠㅠㅠskip...
12장 클래스와 인터페이스
12 - 1. 클래스
- 클래스는 Java의 기본이 되는 구조로, Java 프로그램은 클래스를 기반으로 구성한다. 또한 프로그램으로 취급하는 데이터는 클래스로 분류하여 정리함.
- 클래스 멤버: 클래스의 요소가 되는 것. 생성자, 필드 메소드, 중첩된 클래스. 엄밀히 말하면 생성자는 클래스 멤버가 아니지만 멤버로 침...
- 액세스 한정자: 클래스나 클래스의 멤버를 어디서 사용할 수 있는지에 대한 접근 제어를 지정
액세스 한정자 | 범위 |
private | 같은 클래스에서만 |
default(지정 없음) | 동일한 패키지에서만 |
protected | 같은 패키지 또는 상속한 클래스 |
public | 제한 없음 |
- 생성자(constructor): 객체를 생성할 때 호출되어가는 특별한 메소드. 클래스와 같은 이름의 메소드처럼 정의. 반드시 그 클래스의 객체를 돌려주므로 리턴값을 지정하지 않음.
//생성자 예제
class Student {
private String name;
private int score;
//생성자
Student(String naem, int score) {
this.name = name;
this.score = score;
}
}
- 기본 생성자: 생성자를 정의하지 않는 경우 자동으로 정의되는 빈 생성자. 1개라도 생성자 정의를 기술하면 기본 생성자는 생성되지 않음.
- 생성자 오버로드: 메소드 오버로드와 같이, 인수가 다른 복수의 생성자를 정의하는 것.
- this: 그 객체 자신을 나타내는 키워드. 메소드의 경우 그 메소드가 불려간 객체가 됨. 인수에 필드명과 같은 이름을 붙일 때, 그 이름만을 사용하는 경우 인수 쪽이 우선되고 필드를 지정하고 싶을 때는 this를 붙임
(??) - 필드: 객체에 관한 정보를 보관유지하는 것. final을 붙이면 변경할 수 없는 필드, 안 붙이면 변경할 수 있는 필드. 필드는 private로 하는 경우가 많고 클래스 밖에서 사용하는 경우에는 읽고 쓰기용 메소드를 정의함.
- 엑세스 메소드: 필드의 값을 읽고 쓸 수 있도록 필드에 접근 가능하게 만든 메소드.(getter ,setter)
- static 필드: 클래스에 1개만 영역이 준비된 필드.
- 상수: 프로그램에서 공통으로 사용하는 값 등에 이름을 붙여 한 곳에 정리할 때 사용. 상수의 변수명은 대문자이며 단어를 "_"로 구분. 상수는 의도하지 않고 변경되지 않으므로 대부분의 경우 어디에서나 사용할 수 있도록 public으로 함.
- 추상 자료형: 데이터와 데이터 조작에 관한 방법을 정리한 것. 데이터와 조작을 한꺼번에 취급해 프로그램의 변경을 한 곳에 정리할 수 있다.
- 중첩된 클래스: 클래스 내에서 정의하는 클래스. 반대로 중첩된 클래스를 포함하는 클래스를 외부 클래스라고 함. static이 붙어있지 않은 클래스는 인스턴스 클래스로 내부 클래스(이너 클래스)라고 함.
12 -2. 인터페이스
- 인터페이스: 복수의 클래스에 공통의 성질을 나타내기 위한 구조. 즉, 복수의 클래스가 같은 메소드를 가지고 있는 것을 나타내는 구조.
<인터페이스 예제>
import java.util.List;
public class InterfaceSample2 {
interface Named {
String name();
}
record Student(String name, int score) implements Named{}
record Teacher(String name, String subject) implements Named{}
public static void main(String[] args){
var people = List.of(new Student("sage", 88), new Teacher("hong","Math"));
for (Named p : people) {
var n = p.name();
System.out.println("안녕하세요 %s님".formatted(n));
}
}
}
12 - 3. 람다식과 함수형 인터페이스
- 함수형 인터페이스: 구현할 메소드가 하나만 있는 인터페이스. 람다식은 함수형 인터페이스가 필요한 곳에 지정할 수 있음.
<함수형 인터페이스 람다식 예제>
//Named 인터페이스를 인수에 받는 msg 메소드
static void msg(Named named) {
System.out.println("Hello" + nemed.name());
}
//람다식 사용해 msg 메소드 호출
msg(()->"no name");
//@FunctionalInterface 어노테이션을 사용해 함수형 인터페이스 명시
@FunctionalInterface
interface Named {
String name();
dafault String greeting() {
return "안녕하세요 %s님".formatted(name());
}
}
- @FunctionalInterface 어노테이션은 필수는 아니나 람다식을 받는 것을 전제로 하는 인터페이스에서는 지정하도록..
<표준 API로 제공되는 함수형 인터페이스>
인터페이스명 | 설명 | 인수 | 리턴값 | 메소드 |
Runnable | 처리 전달 | 없음 | 없음 | void run() |
Function<T, R> | 기능 | 있음 | 있음 | R apply(T) |
Consumer<T> | 값으로 처리하기 | 있음 | 없음 | void accept(T) |
Predicate<T> | 판정 | 있음 | 없음 | boolean test(T) |
Supplier<T> | 값 생성 | 없음 | 있음 | T get() |
ActionListener | GUI이벤트 처리 | ActionEvent | 없음 | void actionPerformed(ActionEvent) |