Java projects i have learned
JAVA - 프로그래밍 언어 프로그래밍 언어는 개발자와 운영체제가 소통하기 위한 언어
소스코드 명령어를 작성해 놓은 것. 개발자와 컴퓨터가 소통할 것을 글로 작성해 놓은 것.
컴파일 사람의 언어를 컴퓨터 언어로 바꿔주는 작업.
컴파일러 컴파일을 해주는 프로그램 또는 명령어.
프로그램 소스코드로 잘 짜여진 틀.
콘솔 개발자와 운영체제가 소통한 결과를 보여주는 창.
▶ 일반 프로그램
프로그램 OS(운영체제) : 하드웨어에 적절한 전기신호를 흘려주는 역할. 하드웨어
일반 프로그램 이식성이 좋지 않다.
▶ 자바 프로그램
프로그램 JVM(Java Virtual Machine) -> 자바 가상 운영체제: JAVA 프로그램을 OS에 맞게 번역한다. OS 하드웨어
-JAVA 프로그램은 이식성이 좋다.
JVM(Java Virtual Machine) Java 프로그램을 실행해줌
JRE(Java Runtime Environment) JVM을 생성하며, 실행할 때 필요한 라이브러리 파일들을 가지고 있다.
JDK(Java Development Kit) JRE외에 개발에 필요한 도구들을 가지고 있다. 컴파일 명령어와 실행 명령어를 담고 있다.
JDK 설치 - 11버전
컴파일러 해석 방향 위에서 아래로 좌에서 우로
기본 구조 프로젝트 패키지 클래스(앞글자 대문자) 메소드(이름 뒤에 소괄호) 소스코드
출력 메소드 1. print(): 마직막에 자동으로 줄바꿈되지 않고 아래 문장과 이어서 출력된다. 2. println(): 마지막에 자동으로 줄바꿈된다. 3, printf()
변수 : 저장공간 x = 10 저장공간의 대입 값(상수) 이름 연산자
자료형(type)
자료형 type byte 값
정수형 int 4 1,325,54735, -3343531, .........
실수형 float 4 1.0F, 0.0F, 156.156F, -456.1596F, ...
double 8 1.0, 0.01 156.156, -456.1596...
문자형 char 2 'A', '강', '0', ...
문자열 String ? "한동석", "ABC", "A", "0", "0.1" , ....
변수의 선언
자료형 변수명 = 초기값; ▶ 초기화
자료형 변수명;
예)
int x = 10;
x라는 이름의 저장공간이 할당(allocaiton)되도 그 안에 10이 들어간다.
주소 int x = 10; x라는 이름의 저장공간이 RAM에 할당되면 고유한 값인 주소값이 부여된다. 계속 실행되거나 종료되는 프로그램이 있기 때문에, 주소값은 변경될 수 있으나 중복은 없다.
변수의 사용 int data = 10; // 저장공간 data = 20; // 저장공간 data + 9; // 값 data = data + 99; // 저장공간, 값 System.out.print(data); // 값
변수 선언 시 주의사항 1. 같은 이름의 변수로 선언할 수 없다. 2. 초기화를 해준다.☆ 3. 되도록 선언부에 한꺼번에 선언한다(영역 상단).☆
변수명 주의사항 문자로 시작해야 한다. 특수문자를 사용할 수 없다. 단, _는 허용한다. 소문자로 시작한다. 공백을 사용할 수 없다.
good_boy : 언더바 표기법
goodBoy : 카멜 표기법
되도록 한글은 사용하지 않는다.
명사로 사용한다.
뜻이 있는 단어를 사용한다.
a, b, c, d, e ...(x)
data, number, age, name, ...(o)
변수를 사용하는 이유 1. 반복되는 값을 쉽게 관리하기 위해서 2. 의미 없는 값을 하나의 정보로 만들기 위해서(자료구조)
출력 메소드 printf(): 서식 문자를 사용하여 출력할 수 있으며, 자동으로 줄바꿈되지 않는다.
상수 항상 그대로인 수 값을 변경할 수 없도록 한다.
final 자료형 상수명 = 값;
형변환 - 자동 형변환 정수 + 정수 = 정수 정수 + 실수 = 실수 3 + 0.0 = 3.0 5 / 2 = 2 5 / 2.0 = 2.5 문자 + 정수 = 정수
- 강제 형변환
(자료형)값;
예) (double)3
문자열 형변환
-
다른 자료형을 문자열로 문자열과 다른 일반 자료형을 연결하면 결과는 문자열이 된다.
-
문자열을 다른 자료형으로 일반 자료형은 일반 자료형끼리만 형변환이 가능하다. 문자열 타입은 클래스 타입이므로, 일반 자료형의 클래스 타입의 도움을 받아야 한다.
Integer.parseInt("") => 문자열에서 변환된 정수 값 Float.parseFloat("") => 문자열에서 변환된 실수 값 Double.parseDouble("") => 문자열에서 변환된 실수 값 ============================================================= 입력 커서가 깜빡이고 있는 상태. 입력하기 전에 출력을 통해 어떤 값을 입력해야 할 지 사용자에게 알려주어야 한다.
입력 클래스 Scanner sc = new Scanner(System.in);
입력 메소드 next() : 사용자가 입력한 문자열 값 - 사용자가 입력한 값 중 공백 또는 줄바꿈 문자를 구분점으로 각 문자열을 분리한다 - 첫 번째 문자열은 첫 번째 next()에 담고 - 두 번째 문자열은 두 번쨰 next()에 담는다.
nextLine() : 사용자가 입력한 문자열 값
- 공백 또는 줄바꿈 문자도 값으로 취급하기 때문에 그대로 입력받는다.
연산자 기능이 있는 특수문자
연산자의 우선순위 최우선 연산자 단항 연산자 산술 연산자 쉬프트 연산자 관계 연산자 논리 연산자 삼항 연산자 대입 연산자
결합성 하나의 수식에 동일한 연산자가 여러 개 사용되면 알맞은 방향으로 결합되어 연산되는 성질
논리형(boolean) 참 : true 거짓 : false
boolean(1byte) = true, false
조건식 결과가 참 또는 거짓, 둘 중 하나가 나오는 식. 참 또는 거짓 값. 예) boolean check = 10 == 11;
관계 연산자
== :같다
!= : 같지 않다
>, < : 초과, 미만
>=, <= : 이상, 이하
논리 연산자
&&(AND) , A && B 두 조건식 모두 참이면 참
||(OR), A || B, 둘 중 하나라도 참이면 참
단항 연산자
!(NOT), !A, 조건식이 참이면 거짓으로, 거짓이면 참으로 변경
삼항 연산자
? :, 조건식 ? 참 : 거짓, 조건식이 참이면 참, 거짓이면 거짓
예 ) int result = 10 > 11 ? 10 : 11;
삼항 연산자를 사용해야 할 때
조건식이 딱 한 개 있을 떄
제어문
▶ 조건문 ▷ if 문
if(조건식) {
실행할 문장;
}
f(조건식) {
실행할 문장;
}
f(조건식) {
실행할 문장;
}
f(조건식) {
실행할 문장;
}....
if(조건식){
실행할 문장;
}
else if(조건식){
실행할 문장;
}.....
else{
실행할 문장;
}
▷ switch 문
switch(변수명) {
case 값1:
실행할 문장
break;
case 값2:
실행할 문장
break;
case 값3:
실행할 문장
break;
case 값4:
실행할 문장
break;
default:
실행할 문장
break;
}
삼항 연산자, if문, switch문의 비교
삼항 연산자: 조건식이 1개 있을 경우 사용
if문: 조건식에 비교(>, <, >=, <=) 연산자를 사용하거나, 여러개의 조건식을 논리 연산자로 연결할 떄 사용
switch문: 하나의 변수에 여러 개의 값이 담길 수 있고, 각 값이 같은 지를 비교할 때 사용
대입 연산자(복합 대입 연산자, 누적 연산자) +=, -=, *=, /=, %=
int money = 10000;
// money = money - 1500;
money -= 1500;
System.out.println(money);
int data = 10;
// data = data + 1;
// data += 1;
data++;
System.out.println(data);
증감 연산자 ++, --
전위형 : 해당 라인부터 바로 적용
++data, --data
후위형 : 다음 라인부터 적용
data++, data--
▶ 반복문
▷for문
▷while문 ▷do~while문
반복문
for문
int i = 0; 0 < 10; i = i + 1;
for(초기식;조건식;증감식){
실행할 문장;
}
1. 초기식
-------------
2. 조건식(true)
3. 실행할 문장
4. 증감식
5. 조건식(true)
6. 실행할 문장
7. 증감식
8. 조건식(false)
while문 while(조건식){ 실행할 문장; }
for문과 while문의 차이 - for : 몇 번 반복할 지 알 때 - while : 몇 번 반복할 지 모를 때
do ~ while문 do { 실행할 문장; } while(조건식);
무조건 한 번은 실행되어야 할 때 사용한다.
기타 제어문 break : 즉시 해당 중괄호 영역을 탈출한다. -if문 안에서 사용 시 if문을 탈출하지 않고 if문을 감싸고 있는 중괄호 영역을 탈출한다.
continue : 즉시 다음 반복.
- 아래의 코드를 실행하지 않기 위해서 사용한다.
========================================================= 배열 : 저장공간의 나열 1. 변수를 여러 개 선언하면 이름도 여러 개 생긴다. 이 때 각 저장공간을 관리하기가 불편하다. 따라서 n칸 배열을 한 번만 선언하면 저장공간도 n개 생기고, 이름도 한 개이기 때문에 관리하기 편하다.
2.
규칙성이 없는 값에 규칙성을 부여하기 위해서
배열의 선언 자료형[] 배열명 = {값1, 값2, ......}; // 어떤 값을 넣을 지 알 때 사용 자료형[] 배열명 = new 자료형[칸수]; // 어떤 값을 넣을 지는 모르나, 몇 칸 만들 지는 알 때 사용 자료형[] 배열명 = null; // 어떤 값을 넣을 지도 모르고 몇 칸 만들 지도 모를 때 사용한다.
new : Heap 메모리에 할당, 초기값으로 자동 초기화
null : 주소의 초기값, 어떤 주소를 넣을 지 모를 때 작성하는 값
자바에서 배열은 항상 Heap(동적 메모리)에 할당되기 때문에 메모리 상으로는 동적배열만 존재한다.
배열의 구조 ▶ 반복문
▷ for문
int i = 0; i < 10; i = i + 1 for(초기식; 조건식; 증감식){ 실행할 문장; }
- 초기식
- 조건식(true)
- 실행할 문장
- 증감식
- 조건식(true)
- 실행할 문장
- 증감식
- 조건식(false)
▷ while문 while(조건식){ 실행할 문장; }
for문과 while문의 차이
- for : 몇 번 반복할 지 알 때
- while : 몇 번 반복할 지 모를 때
▷ do ~ while문 do { 실행할 문장; } while(조건식);
무조건 한 번은 실행되어야 할 때 사용한다.
기타 제어문 break : 즉시 해당 중괄호 영역을 탈출한다. - if문 안에서 사용 시 if문을 탈출하지 않고 if문을 감싸고 있는 중괄호 영역을 탈출한다.
continue : 즉시 다음 반복. - 아래의 코드를 실행하지 않기 위해서 사용한다.
============================================================================== 배열 : 저장공간의 나열 1. 변수를 여러 개 선언하면 이름도 여러 개 생긴다. 이 때 각 저장공간을 관리하기가 불편한다. 따라서 n칸 배열을 한 번만 선언하면 저장공간도 n개 생기고, 이름도 한 개이기 때문에 관리하기 편하다. 2. 규칙성이 없는 값에 규칙성을 부여하기 위해서
배열의 선언 자료형[] 배열명 = {값1, 값2,...}; // 어떤 값을 넣을지 알 때 사용 자료형[] 배열명 = new 자료형[칸수]; // 어떤 값을 넣을지는 모르나, 몇 칸 만들지는 알 때 사용 자료형[] 배열명 = null; // 어떤 값을 넣을지도 모르고 몇 칸 만들지도 모를 때 사용한다.
※ new: Heap 메모리에 할당, 초기값으로 자동 초기화 ※ null: 주소의 초기값, 어떤 주소를 넣을 지 모를 때 작성하는 값 ※ 자바에서 배열은 항상 Heap(동적 메모리)에 할당되기 때문에 메모리 상으로는 동적배열만 존재한다.
배열의 구조 int[] arData = {3, 5, 1, 2, 8};
arData라는 이름의 저장공간은 한 개 만들어지며, 여기에는 한 개의 값만 담을 수 있다. 5개의 값을 담기 위해서는 5칸이 필요하며, 이는 Heap 메모리에 할당된다. 5칸의 저장공간 중 첫 번째 저장공간의 주소값이 arData 저장공간으로 들어가며, 다음 주소에 접근하기 위해서는
- n을 한다. 예를 들어 arData + 2는 1이라는 값이 담긴 주소값이 되며, *(arData + 2)는 해당 주소에 가서 읽어온 1이라는 값이 된다. JAVA에서는 직접 주소에 접근하는 연산자가 없기 때문에 위와 같은 식을 []로 치환하여 사용하며, arData[2]로 사용한다. 각각의 방 번호는 index라고 부르며, 배열은 시작주소를 가지고 있기 때문에 인덱스 번호는 항상 0부터 시작된다.
length 배열을 선언하면 length라는 상수가 선언되고, 해당 배열의 길이가 담긴다. 배열명.length로 사용하게 된다.
배열의 사용 int[] arData = new int[5]; // 저장공간 arData[0] = 10; // 저장공간 arData[0] + 9; //값 System.out.println(arData); // 주소값 arData[2] = arData[0] + arData[1]; // 저장공간, 값 System.out.println(arData[5]); // 오류
2차원 배열 : 배열 안에 배열 1차원 배열을 여러 개 선언할 때 관리하기 힘들기 때문에 2차원 배열을 한 번 선언한다.
※ 2차원 배열부터는 메모리 낭비가 심하므로 선호하지 않는다.
2차원 배열 선언 자료형[][] 배열명 = {{값1, 값2, 값3,...}, {값4, 값5, 값6,...}}; 자료형[][] 배열명 = new 자료형[행][열]; 자료형[][] 배열명 = null;
int[][] arrData = new int[2][3];
□ arrData arrData.length(행의 길이)
□□ arrData[행] arrData[행].length(열의 길이)
□□□ □□□ arrData[행][열]
=================================================== 메소드 이름 뒤에 소괄호 단, 키워드 뒤에 소괄호는 메소드가 아니다(if, for 등등)
f (x) = 2x+1
메소드 이름 매개변수 리턴값
메소드 선언 (1)리턴타입 (2)메소드명(자료형 (3)매개변수명, ...){ (4)실행할 문장; (5)return 값; }
(1) 리턴 값이 있다면 리턴 값의 자료형을 작성하고, 리턴 값이 없다면 비워놓지 않고 void를 작성한다.
(2) 동사로 작성한다(연필(매개변수)을 쓴다(메소드)).
(3) 외부에서 전달받을 값이 있다면, 자료형과 순서에 맞게 선언해준다.
생략 시, 외부에서 값을 전달받을 수 없게 된다.
(4) 생략이 가능하다. 메소드의 기능을 구현하는 로직을 작성한다.
(5) 생략이 가능하다. 리턴값이 있다면, 사용한 부분 통째로 리턴값으로 봐야한다.
메소드 선언 순서 문제) 두 정수의 덧셈 메소드 선언
-
메소드 이름을 생각한다. add(){}
-
매개변수를 생각한다. add(int number1, int number2){}
-
실행할 문장을 작성한다. add(int number1, int number2){ int result = number1 + number2; }
-
리턴 값을 작성한다. add(int number1, int number2){ int result = number1 + number2; return result; }
-
리턴타입을 결정한다. int add(int number1, int number2){ int result = number1 + number2; return result; }
메소드 주의사항 메소드를 선언할 때에는 {}(중괄호)가 있으며, 반드시 메소드 밖에서 선언한다. 메소드를 사용할 때에는 {}(중괄호)가 없으며, 반드시 메소드 안에서 사용한다.
클래스 공통요소를 한 번만 선언해놓고 가져다 사용만 하도록 설계한다.
1. 타입이다
클래스 안에 선언된 변수와 메소드를 사용하고 싶다면,
해당 클래스 타입으로 변수를 선언해야 한다.
2. 주어이다
원숭이가 먹는다 바나나를
Monkey.eat("banana");
클래스 선언 class 클래스명 { 필드(변수, 메소드) }
클래스의 필드 사용 1. 객체화(instance) : 객체(instance variable)를 만드는 작업, 추상적인 개념을 구체화 시키는 작업. 클래스명 객체 = new 생성자();
※ .(마침표): 하위 연산자, 멤버변수 접근 연산자, 닷 연산자, 점 연산자
주소값 뒤에서만 사용이 가능하며, 해당 주소를 참조하는 명령어이다.
2. static : 모든 객체가 공유해야 하는 필드일 경우에 사용한다.
클래스 하나 당 한 개만 생기기 때문에 객체로 접근하지 않고 클래스로 접근한다.
생성자 클래스 이름 뒤에 소괄호가 있는 형태, 메소드와 기능이 똑같지만 메소드라고 부르지 않는다. 생성자는 리턴이라는 기능이 존재하지 않기 때문이다.
1. 해당 클래스의 필드를 메모리에 할당한 후 부여된 주소값을 가져온다.
2.
기본 생성자 매개변수가 없는 생성자이며, 클래스 선언 시 자동으로 선언된다. 사용자가 직접 생성자를 선언하게 되면 기본 생성자는 없어진다.
this 필드에 접근한 객체가 누구인지 알아야 해당 필드에 접근할 수 있다. 이 때 접근한 객체가 가지고 있는 필드의 주소값은 this라는 변수에 자동으로 담긴다.
다형성 1. 오버로딩(overloading) 매개변수의 개수 또는 타입이 다르면 동일한 이름의 메소드로 선언할 수 있다. 2.
[클래스 실습] 학생 클래스 학생 번호 국어 점수 영어 점수 수학 점수
학생의 점수를 입력받은 뒤 총 점과 평균 출력
※ 생성자를 사용한다
상점 클래스
상품명
상품 가격
재고
손님 클래스
이름
휴대폰 번호
통장 잔고
할인율
상점에서 상품 판매 시 손님의 할인율을 적용하여 판매
상속(inheritance)
- 기존에 선언된 클래스의 필드를 새롭게 만들 클래스의 필드로 사용하고자 할 때
- 여러 클래스 선언 시 필드가 겹칠 때 부모 클래스를 먼저 선언하고 공통 필드를 묶어서 자식 클래스들에게 상속해준다.
상속 문법 class A { A 필드 }
class B extends A { A, B 필드 }
A: 부모 클래스, 상위 클래스, 슈퍼 클래스, 기반 클래스 B: 자식 클래스, 하위 클래스, 서브 클래스, 파생 클래스
super(): 부모 생성자 자식 클래스 타입의 객체로 부모 필드에 접근할 수 있다. 하지만 자식 생성자만 호출하기 때문에, 자식 필드만 메모리에 할당한다고 생각할 수 있다. 사실 자식 생성자에서 항상 부모 생성자를 호출하기 때문에 자식 생성자 호출 시 부모와 자식 필드 모두 메모리에 할당된다. 이 때 부모 생성자를 호출하는 방법은 super()를 사용하는 것이다. 만약, super()를 작성하지 않더라도 컴파일러가 자동으로 작성해준다.
다형성(polymorphism)
- 오버로딩
- 오버라이딩(재정의) 부모 필드에서 선언한 메소드를 자식 필드에서 수정하고자 할 때 재정의를 해야 한다. 이는 자식에서 부모 필드의 메소드와 동일한 이름으로 선언하는 것이다. 부모 필드가 메모리에 먼저 할당되고 a라는 메소드가 먼저 올라간다고 하면, 자식 필드가 메모리에 할당되면서 재정의한 a메소드가 새롭게 만들어지는 것이 아니라 기존에 할당된 a메소드 저장공간에 새롭게 재정의한 자식 필드의 소스코드 주소가 들어가게 된다. 따라서 자식 객체로 a메소드에 접근하면 자식 필드에서 재정의한 소스코드의 내용이 읽히게 된다.
접근 권한 제어자(접근자) default : 다른 패키지에서 접근 불가 public : 모든 곳에서 접근 가능 protected : 다른 패키지에서 접근 불가 private : 다른 클래스에서 접근 불가 ☆☆☆
※ 모든 자식은 부모 타입이다.☆☆☆
Casting 1. up casting 자식 값을 부모 타입으로 형변환
2. down casting
up casting된 객체를 자식 타입으로 형변환
※ 부모 값을 자식 타입으로 형변환 시 오류
=========================================================
[종합 실습] 은행 예금주 계좌번호(중복 없음) 핸드폰번호(중복 없음) 비밀번호 통장잔고
신한 입금 시 수수료 50% 국민 출금 시 수수료 50% 카카오 잔액조회 재산 반토막
은행은 3개를 선언한다. 모든 은행 고객을 관리하는 DB를 2차원 배열로 선언한다. -> Bank 클래스에 모든 은행은 출금, 입금, 잔액조회, 계좌개설, 계좌번호 중복검사, 로그인(계좌번호, 비밀번호), 핸드폰 번호 중복검사 서비스가 있다. -> 중복검사, 로그인, 핸드폰 번호 static 화면쪽 메뉴는 "계좌개설, 입금하기, 출금하기, 잔액조회, 계좌번호 찾기(새로운 계좌발급, 핸드폰 번호로 서비스 이용가능), 나가기"로 구성되어 있다. 계좌번호는 Random클래스를 사용하여 6자리로 설정한다. 계좌를 개설한 은행에서만 입금 서비스를 이용할 수 있다(instanceof) 각 은행별 인원 수를 담을 3칸 배열 선언(계좌 개설 시 신규 고객이 들어갈 열 번호) 각 은행별 객체 3개를 담을 3칸 배열 선언(계좌 개설 시 고객이 선택한 은행 객체)
추상 클래스 필드 안에 구현이 안 된 메소드가 선언되어 있는 클래스를 추상 클래스라고 한다. 이 때 구현되지 않은 메소드를 추상 메소드라고 부른다. 반드시 재정의를 통해 구현을 해야지만 메모리에 할당되기 때문에 "강제성"을 부여하기 위해서 추상 메소드로 선언한다.
인터페이스(틀) 추상 클래스를 고도화시킨 문법, 상수와 추상 메소드만 존재한다. 구현은 지정한 클래스에서 진행하고, 인터페이스를 다른 클래스에 지정할 때에는 implements 키워드를 사용한다.
추상 클래스와 인터페이스 간의 관계 인터페이스를 클래스에 바로 지정하면 모든 메소드에 강제성이 부여되어서 전부 다 구현해야 한다. 하지만 일반적인 상황에서는 모든 것이 아닌, 필요한 메소드를 골라서 재정의해야 한다. 인터페이스를 직접 지정하지 않고 다른 클래스에 지정한 후 바디를 만들어 놓는다면, 강제성이 소멸되고 이 클래스를 상속받아서 필드를 구현한다면, 골라서 재정의할 수 있게 된다. 이 때 중간에서 강제성을 없애주는 클래스를 추상 클래스로 선언하기로 하며, 추상 클래스 이름 뒤에는 Adapter를 붙여서 목적을 알려준다.
마커 인터페이스(Marker Interface) 클래스들을 그룹화하기 위한 목적으로 사용한다. 인터페이스는 지정한 클래스의 부모이며, 모든 자식은 부모의 타입이므로 마커 인터페이스를 지정받은 클래스들이 하나의 타입으로 묶이게 된다. 이름 뒤에 Marker를 붙여줘야 한다.
내부 클래스(Inner class): 어떤 영역 안에 클래스가 선언되면 내부 클래스라고 한다. 하나의 클래스에서 a작업과 b작업이 있을 때에는 따로 분리하여 클래스로 만들지 않고, 클래스 안에 클래스를 선언하여 설계한다. 이 때 밖에 있는 클래스를 외부 클래스라고 하며, 안에 선언된 클래스를 내부 클래스라고 한다. 외부 클래스가 메모리에 할당되어야 내부 클래스를 객체화할 수 있기 때문에 클래스를 숨기기 위해서 내부 클래스를 사용하기도 하며, 이를 캡슐화 또는 은닉화라고 한다. 내부 클래스는 외부 클래스의 필드이기 때문에 외부 클래스의 필드는 자신의 필드처럼 가져다 사용할 수 있지만 상속관계가 아니기 때문에 내부 클래스일지라도 extends를 통해 다른 클래스를 상속받아서 사용할 수 있다.
익명 클래스(Anonymous Inner Class)☆ 이름이 없는 클래스이며 구현되지 않은 필드를 구현하기 위해서 일회성으로 생성되는 클래스이다.
다중 상속 여러 부모 클래스를 상속하는 것을 다중 상속이라고 한다. JAVA는 모호성 때문에 다중 상속을 지원하지 않는다. 하지만 JDK8 버전부터는 인터페이스에 default 메소드를 선언할 수 있으며 여러 개를 지정할 수 있는 인터페이스 특성상 다중 상속을 지원하는 것이나 다름이 없다.
모호성(ambiguity) 하나의 자식이 여러 부모를 상속받을 때 부모 필드에 동일한 이름의 필드가 있다면, 어떤 부모의 필드인지 알 수가 없다. 이를 모호성이라고 부른다.
모호성 해결 방법
-상황1: 두 개의 인터페이스 내에 이름과 매개변수가 똑같은 메소드가 선언되어 있다. -해결1: 자식 클래스에서 재정의하여 사용한다. 원하는 부모의 필드에 접근하기 위해서는 "부모명.super.필드명"을 작성한다.
-상황2: 부모 클래스의 public 메소드와 인터페이스의 디폴트 메소드의 이름과 매개변수가 똑같이 선언되어 있다. -해결2: 부모 클래스의 메소드가 사용된다.
함수형 인터페이스(Functional Interface) 인터페이스 중 추상메소드를 하나만 가지고 있는 인터페이스를 함수형 인터페이스라고 한다. 이 떄 @FunctionalInterface를 인터페이스 위에 작성하며 단 하나의 추상 메소드만 선언할 수 있도록 제한해야 한다.
람다식(Lambda Expression) 함수형 인터페이스에서는 한 개의 추상메소드만 존재하기 때문에 구현 시 메소드 이름이 딱히 필요가 없다. 람다식은 이름이 없는 메소드로서 값처럼 사용이 가능하며, 매개변수로도 전달이 가능하다. 따라서 람다식을 익명 메소드(Anonymous Method)라고도 부른다.
람다식 문법 1. (매개변수 형식 나열, ...) -> 리턴값; 2. (매개변수 형식 나열, ...) -> {2개 이상의 문장 작성; return 리턴값; } ※ 매개변수가 1개일 경우 소괄호 생략 가능(매개변수가 아예 없거나 2개 이상일 경우 소괄호를 반드시 작성해야 한다)
람다식 기초 실습 package는 lambdaTask1로 선언한다.
PrintName 인터페이스 선언
getFullName() 추상 메소드 선언
- 성과 이름을 전달받는다.
PrintNameTest 클래스 선언
PrintFullName() 메소드 선언
- 외부에서 구현된 PrintName을 전달받은 뒤 전체 이름을 출력
[심화 실습] 여러 개의 정수를 입력받아서 알맞는 덧셈, 뺄셈 결과를 확인하는 애플리케이션 제작
입력 예1) 7 + 35 - 9 출력 예1) 33
입력 예2) -9 + 8 + 10 출력 예2) 9
-
"ABC".split("")은 [A][B][C] 3칸 문자열 배열로 리턴된다. "A,B,C".split(",")은 [A][B][C] 3칸 문자열 배열로 리턴된다. split("구분점")을 전달하면 문자열에서 동일한 구분점을 기준으로 문자열 값을 잘라낸 후 문자열 배열로 리턴한다. 구분점을 여러 개 사용할 때에는 split("구분점|구분점")으로 사용하며, "+", "-"를 구분점으로 사용할 때에는 "\+", "\-"로 표현한다. 예)"4 + 9".split("\+")은 [4][9] 2칸 문자열 배열로 리턴
-
사용자가 정상적으로만 입력한다는 가정 하에 구현하도록 한다.
-
두 정수를 전달받은 후 int로 리턴하는 calc 추상메소드 선언(함수형 인터페이스 제작)
-
두 정수의 덧셈, 뺄셈을 구해주는 함수형 인터페이스를 리턴하는 static 메소드 선언(람다식 리턴)
-
전체 식을 전달받은 후 String[]로 리턴하는 getOpers 추상메소드 선언(함수형 인터페이스 제작) - OperCheck
-
main메소드에 getOper를 람다식으로 구현 - MyMath
-
첫번째 정수가 음수일 경우 오류 해결
예외 처리 컴파일 시, 빌드 시, 런타임 시 오류가 발생하면 여러가지 오류가 발생한다. 보통 오류가 발생하지 않도록 제어문을 사용하지만, 제어문을 사용할 수 없을 경우 예외 처리 문법을 사용한다.
예외 처리 문법 try{ 오류가 발생할 수 있는 문장 }catch(예외이름 객체명){ 오류 발생 시 실행할 문장 }...
} finally {
catch에서 잡히지 않은 오류가 있더라도 무조건 실행
}
예외 발생 직접 예외를 발생시키기 위해서는 예외 던지기를 사용해야 하며, 이 때에는 생성자 호출 전 throw 키워드를 사용한다. 예) throw new BadWordException();
사용자 정의 예외 기본적으로 제공되는 예외가 아닌 특정 상황에서 직접 예외를 만들어야 한다면, Exception 혹은 RuntimeException을 상속받아서 예외 클래스를 선언해야 한다. Exception은 컴파일러가 체크를 하기 때문에 예외처리를 강제로 해야하고, RuntimeException은 컴파일러가 체크하지 않기 때문에 예외처리를 선택할 수 있다.
API(Application Programming Interface)
API(Application Programming Interface) 개발에 필요한 라이브러리들의 집합. 선배 개발자들이 만들어 놓은 소스코드.
-
내부 API JDK 설치 시 제공해주는 기본 API docs.oracle.com/javase
-
외부 API 선배 개발자들이 개발한 패키지 및 클래스들을 의미한다. 보통 JAR파일로 배포하며 자바 프로젝트의 build path에 추가하여 사용할 수 있다.
JAR 파일로 배포하기 배포할 클래스 또는 패키지 우클릭
Export > JAVA/JAR file 선택 > Next destination을 원하는 경로로 선택 Export Java source files... 체크 Finish
JAR 파일을 프로젝트에 추가하기 배포된 JAR파일을 다운 받기
프로젝트 우클릭 > Build Path > Configure Build Path Libraries 탭 클릭 > ClassPath(안되면 ModulePath) 클릭 > Add External JARs 저장된 경로의 .jar파일을 더블 클릭으로 추가 > Apply 클릭 Orders and Exports 탭 클릭 Select All 클릭 > Apply and Close
Object 클래스 1. toString() 항상 객체명을 출력할 때에는 toString()을 붙여서 출력해준다. 따라서 객체명만 출력메소드에 전달하더라도 toString()의 문자열 값이 출력된다. 기본적으로 Object에서는 소속과 필드 주소를 문자열로 리턴해주지만, 실사용에서는 불필요한 정보이기 때문에, 재정의한 뒤 필드의 정보를 확인하도록 구현한다. 실무에서는 클래스 선언 시 각 필드의 초기화 여부를 확인하기 위해 toString()을 재정의하여 사용한다. 2. equals() ☆ 주소값을 비교하는 메소드이며 ==과 동일하다. String 클래스에서 equals()를 값 비교로 재정의하여 사용하기 때문에 문자열 비교는 무조건 equals()로 비교한다. 만약 주소 비교가 아닌 원하는 필드의 비교가 필요하다면 반드시 equals()를 재정의 해서 사용해야 한다.
3. hashCode()
Object 클래스 1. toString() 항상 객체명을 출력할 때에는 toString()을 붙여서 출력해준다. 따라서 객체명만 출력메소드에 전달하더라도 toString()의 문자열 값이 출력된다. 기본적으로 Object에서는 소속과 필드 주소를 문자열로 리턴해주지만, 실사용에서는 불필요한 정보이기 때문에, 재정의한 뒤 필드의 정보를 확인하도록 구현한다. 실무에서는 클래스 선언 시 각 필드의 초기화 여부를 확인하기 위해 toString()을 재정의하여 사용한다. 2. equals() ☆ 주소값을 비교하는 메소드이며 ==과 동일하다. String 클래스에서 equals()를 값 비교로 재정의하여 사용하기 때문에 문자열 비교는 무조건 equals()로 비교한다. 만약 주소 비교가 아닌 원하는 필드의 비교가 필요하다면 반드시 equals()를 재정의 해서 사용해야 한다.
3. hashCode() -> equals()와 한 쌍
JVM에서 관리하는 중복 없는 값. 실제 메모리에 할당되는 주소와 다르다.
String 클래스에서는 필드의 해시코드 값이 아닌 문자열 상수값의 해시코드를 리턴하도록 재정의하였다.
※ 컬렉션 프레임워크 챕터에서 재정의 목적을 이해하도록 한다.
============================================================================= Wrapper Class: 기본 자료형들의 클래스 타입 클래스타입 객체 = new 클래스타입(일반타입의 값); // boxing, 권장하지 않는다(Deprecated). 클래스타입 객체 = 클래스타입.valueOf(일반타입의 값); // boxing 일반타입 변수 = 객체.000Value(); // Unboxing
JDK4버전 이상부터는 auto를 지원한다.
클래스타입 객체 = 일반타입의 값; // auto boxing
일반타입 변수 = 객체; //auto unboxing
============================================================================= 알고리즘 어떤 문제가 발생되었을 때 해결할 수 있는 절차 혹은 순서.
자료구조(저장소) 의미 없는 데이터를 하나의 정보로 만들어주는 알고리즘들의 집합. 수집한 자료를 저장하는 방법.
컬렉션 프레임워크(Collection Framework) ☆☆ 많은 데이터를 쉽고 효과적으로 관리할 수 있는 표준화된 방법을 제공하는 클래스들의 집합.
-
List extends Collection
- Vector: 용량 관리, 보안성 강화, 처리량 감소
- LinkedList: FILO로 인해 넣을 때는 빨라도 원하는 위치의 데이터를 가져오는 것이 상대적으로 느리다.
- ArrayList☆☆☆: 인덱스로 데이터를 관리한다. 컬렉션 클래스 중 실무에서 가장 많이 사용되는 클래스이다. 배열의 특징인 인덱스를 이용하여 값을 저장하고 관리한다.
※ 배열과 ArrayList의 차이 배열은 길이에 제한을 두어야 할 때 자주 사용되고 ArrayList는 몇 개의 데이터가 들어올 지 알 수 없을 때 사용한다.
[심화 실습] User 클래스 선언 - 이름, 아이디, 비밀번호, 휴대폰번호 - private 접근자 사용 - 기본 생성자 선언 - toString() 재정의
DBConnecter 클래스 선언
- 회원 정보를 담을 DB ArrayList로 선언
UserField 클래스 선언
- 아이디 중복검사
- 회원가입
- 로그인
- 암호화
- 비밀번호 변경(마이 페이지)
- 인증번호 전송
- Set extends Collection
- Map
[ArrayList 실습1]
과일 정보를 담을 클래스 선언(Fruit)
- 과일 이름(중복 없음)
- 과일 가격
CRUD관련 기능을 담아놓을 클래스 선언(Market)
- 과일 추가
- 과일 삭제
- 과일 가격이 평균 가격보다 낮은 지 검사
- 과일 전체 조회
- 과일 이름으로 가격 조회
[ArrayList 실습2]
음식 정보를 담을 클래스 선언(Food)
- 음식 이름
- 음식 가격
- 음식 종류(한식, 중식, 일식, 양식)
CRUD관련 기능을 담아놓을 클래스 선언(Restaurant)
- 음식 추가
- 음식 이름으로 음식 종류 조회
- 사용자가 원하는 종류의 음식 전체 조회
- 음식 종류 수정 후 가격 10% 상승
- 사용자가 원하는 종류의 음식 개수 조회
[ArrayList 실습3]
이상형 정보를 담을 클래스 선언(Love)
- 번호
- 이름
- 나이
CRUD관련 기능을 담아놓을 클래스 선언(DateApp)
- 사용자가 원하는 나이의 이상형 목록 조회
- 이상형의 나이 수정
- 이상형 나이 순 정렬
[ArrayList 실습4] 본인이 주제 선정해서 만들기
- Set extends Collection
-
구현 클래스 HashSet 집합에서는 중복되는 원소를 포함할 수 없는 것 처럼 HashSet이라는 자료구조는 중복되는 값을 무시한다. 저장된 값들은 인덱스가 없기 때문에 순서가 없다. '값의 유무 검사'에 특화되어 있는 자료구조이고 해시코드로 유무 검사가 진행되기 때문에 속도가 상대적으로 좋다.
-
순서 부여 iterator() 순서가 없는 객체에 순서를 부여하거나, 순서가 있어도 iterator방식의 순서로 변경하고자 할 때 사용한다. hasNext()를 통해 다음 값이 있는 지 검사하고, next()를 사용해서 값을 가져온다. ===========================================================================================
- Map
-
구현 클래스 HashMap(서버 간 데이터 교환) ☆☆☆ Key와 Value 한 쌍으로 저장되며, 검색의 목적을 가지고 있다. Key에 중복된 값을 넣으면 Value가 최근 값으로 수정되고, 중복되지 않은 값을 넣으면 새롭게 추가된다. Value는 중복이 가능하다.
Key : Set, Value : Collection
프로그램 실행이 안 된 상태
프로세스 실행된 프로그램
쓰레드 프로세스 내의 작업 처리 경로
- 단일 쓰레드
처리 경로를 한 개만 가지고 있기 때문에 직렬적이다.
한 번에 하나씩 처리하기 떄문에 상대적으로 비효율적이다.
하지만 하나의 작업에 문제가 발생하더라도 다른 작업은 시작하지 않았기 때문에
다른 작업에는 문제가 발생하지 않는다. 따라서 안정성이 보장되고 설계 시
멀티 쓰레드에 비해 쉽다.
- 멀티 쓰레드
하나의 프로세스를 동시에 처리하는 것처럼 보이지만 사실은 매우 짧은 단위로 분할해서 차례로 처리한다.
여러 개의 처리 경로를 가질 수 있도록 하며, 동시 작업이 가능하다.
설계하기 굉장히 어려우며, 하나의 쓰레드 문제 발생 시 모든 쓰레드에 문제가 발생하게 된다.
멀티 쓰레드로 설계했다면, 처리량 증가, 효율성 증가, 처리비용 감소의 장점이 있기 떄문에
단점을 감수하고 처리하는 편이다.
멀티 쓰레드구현 방법 핵심: run() 메소드 재정의
1. Thread 클래스 상속
2. Runnable 인터페이스 지정
Thread 종료 방법
- 필드에 boolean 타입의 변수를 선언하고 run()안에 있는 반복문에 해당 변수가 true일 경우 break 하도록 설계한다.
- sleep() 또는 wait(), join() 등의 메소드를 통해 쓰레드 일시정지 상태일 경우 Thread객체.interrupt()를 사용하여 InterruptedException을 발생시킨다. 이 때 일시정지 시킨 메소드 부분의 catch를 통해 예외를 잡아주고 원하는 문장을 작성하면 된다.
- 쓰레드를 일시정지하는 코드가 없을 경우 Thread.interrupted()의 상태를 확인한다. Thread객체.interrupt() 사용 시 Thread.interrupted()의 상태는 true로 변경된다.
- System.exit(0)를 사용하면 전체 쓰레드 종료(프로세스 종료)
※ 반드시 join()을 사용한다. ※ 각 동물은 10번씩만 운다. ※ 람다식을 사용한다.
============================================================ 파일 입출력
Stream이라는 연결통로를 통해 원본 데이터가 알맞는 인코딩 방식으로 전송된다. byte단위로 입출력되기 때문에 개별처리이며, 상세 연산이 필요하지 않다면 Buffer를 사용한 입출력을 권장한다. Buffer를 사용하면 일괄처리가 가능해진다.
※ 인코딩 방식 인코딩 방식은 완성형과 조합형이 있다. - 완성형: 각, 간, 갇, 갈, 감, ... , 갛, ... - 조합형: ㄱ + ㅏ + ㄱ
조합형이 효율적이며 byte단위로 데이터를 전송할 때 고정된 byte가
아니기 때문에 가변형 인코딩 방식을 선호한다.
조합형이면서 가변형인 인코딩 방식은 UTF-8이며, 전 세계에서 가장 많이
사용되는 방식이다.
Writer(출력) BufferedWriter : 버퍼를 사용한 출력 클래스 FileWriter : 전달한 경로의 파일을 출력하기 위한 목적으로 열어준다. 전달한 경로에 파일이 없다면 새롭게 만든 후 열어준다.
Reader(입력) BufferedReader : 버퍼를 사용한 입력 클래스 FileReader : 전달한 경로의 파일을 입력하기 위한 목적으로 열어준다. 전달한 경로에 파일이 없다면 FileNotFoundException이 발생한다.
File(파일 정보) 전달한 경로에 있는 파일의 정보를 담는 타입 디렉터리 생성, 해당 경로의 전체 파일 목록, 파일 삭제 등
소프트웨어 디자인 설계 패턴 ▶ MVC M(Model): 테이블에서 조회된 결과 값을 담기 위한 변수들이 선언된 클래스 - 클래스명 뒤에 VO, DTO라는 문자열을 붙여준다. - VO(Value Object): 테이블을 보고 그대로 만든 객체 - DTO(Data Transfer Object): 화면에 결과를 한 번에 묶어서 전달할 객체 V(View): 사용자에게 보여질 화면을 구성하는 부분 - Controller에 선언된 CRUD 메소드를 사용하는 부분
C(Controller): JSP 챕터에서 더 자세히 알아보자
DAO(Data Access Object): 테이블에 접근할 수 있는 메소드들이 선언된 클래스
- 접근 후 결과 값이 있을 경우 Model 객체에 담은 후 처리
- 클래스명 뒤에 DAO라는 문자열을 붙여준다.