diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..24ec2e18 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.gradle +*.idea +build +gradle +out +gradlew +*.bat diff --git a/4weeks/1.practical training.md b/4weeks/1.practical training.md new file mode 100644 index 00000000..571ea190 --- /dev/null +++ b/4weeks/1.practical training.md @@ -0,0 +1,182 @@ +# 자바 코드 실습 + + +## 협업 + +- 합의에 도달하기 위한 갈등 과정은 자연스러운 것임을 받아들인다. + +- 서로에게 기대하는 바를 명확히 한다. 무루숭실한 표현은 추후 갈등이나 키운다. 따라서 기대한 산출물이 있다면 그것이 무엇인지 명확히 하고, 변경 가능성이 있는 것들은 그 내용이 무엇인지 미리 알려주는 것이 좋다. + +- 내 의견과 다른 의견, 원래 계획에서 달라진 상항들을 포용하려고 노력한다. 전문 분야, 경험, 개인적 목표가 다르기 때문에 다른 의견이 나오는 것은 당연하다. 자신의 의견만 관철시키려 하기보다 조직의 목표 달성을 위해 구성원이 합의할 수 있는 사항을 정의해가는 것이 중요하다. 또한 상황 변화에 따른 계획 변경에 대해서도 유연하게 대처하는 자세가 필요하다. + +- 다른 구성원과 유대감을 형성하거나 유지하기 위해 지속적으로 커뮤니케이션한다. 업무와 관련된 것뿐 아니라, 상대방이 관심을 보이는 정보를 공유하는 것도 한 방법이다. 예를 들면, 세미나 정보나 뉴스링크를 이메일로 보내주는 것이다. 때로 개인적인 경험을 공유하는 경우도 있으나 이것은 유대감의 긴밀도나 상대방의 특성에 따라 결정해야 할 문제다. + +- 상호 신뢰는 협업에서 가장 중요한 부분이다. 신뢰를 쌓으려면 말뿐 아니라 행동으로 보여야 한다. 약속이나 기한을 잘 지키는 것이 대표적인 예다. 문제가 생겼을 때 바로 공유하고 이를 해결하기 위해 도움을 주고 받는 것도 신뢰를 쌓는 방법이 될 수 있다. + +- 협업 도구를 적극적으로 활용하라. 구글 드라이브, 에버노트, 트렐로, 레드 펜, 인비전, 마인드 마이스터, 깃허브 등. 프로젝트의 성격과 산출물의 유형에 따라 적합한 도구를 이용하는 것도 협업의 성과에 큰 도움을 준다. + +- 협업에 방해되는 요인이 있다면, 구성원 또는 당사자와 공유하고 정정될 수 있도록 초기에 노력하는 것이 중요하다. 단, 특정 구성원이 다른 구성원 앞에서 당황스러움을 느끼게 해서는 안 된다. + + +## 역할, 책임, 협력(Role, Responsibility, collaboration) + +### 객체지향 +1. 객체들이 어플리케이션의 기능을 구현하기 위해 수행하는 상호작용을 **협력**이라고 한다. +2. 객체가 협력에 참여하기 위해 수행하는 로직은 **책임**이라고 한다. +3. 객체들이 협력 안에서 수행하는 책임들이 모여 객체가 수행하는 **역할**을 구성한다. + +### 역할 +- 객체가 어떤 특정한 협력 안에서 수행하는 책임의 집합을 역할이라 한다. +- 협력이라는 문맥 안에서 필요한 책임을 추렸다면, 해당 책임을 가지고 있어야 할 역할이 무엇인지 개념을 뽑아내고 그 다음에 역할에 맞는 이름을 부여하여 클래스로 만든다. +#### 유연하고 재사용 가능한 협력 +- 역할을 통해 유연하고 **재사용 가능한 협력**을 얻을 수 있다. +- 역할에 집중하면 추상적인 네이밍을 가져도 문맥은 유지가 되고, 비슷한 구현의 다른 객체를 추가하는 데 큰 비용이 들지 않는다. +- 객체에게 중요한 것이 행동임은 변함이 없다. 역할은 동일한 협력을 수행하는 객체들을 추상화할 수 있다. + +### 책임 +#### 하는 것 +- 객체를 생성하거나 계산 수행하는 등의 스스로 하는 것 +- 다른 객체의 행동을 시작시키는 것 +- 다른 객체의 활동을 제어하고 조절하는 것 +#### 아는 것 +- 사적인 정보에 대해 아는 것 +- 관련된 객체에 대해 아는 것 +- 자신이 유도하거나 계산할 수 있는 것에 대해 아는 것 + + +- 객체에 의해 정의되는 응집도 있는 행위의 집합이자, 객체가 유지해야 하는 정보와 수행할 수 있는 행동에 대해 개략적으로 서술한 문장을 책임이라고 한다. +- 책임은 메시지보다 추상적이고 개념적으로도 더 크다. +- 객체지향 설계에서 책임을 얼마나 적절한 객체에게 할당하느냐가 설계가의 전체적인 품질을 결정한다. +#### 책임주도 설계 +- 시스템이 사용자에게 제공해야 하는 기능인 시스템 책임을 파악한다. +- 시스템이 책임을 더 작은 책임으로 분할한다. +- 분할된 책임을 수행할 수 있는 적절한 객체 또는 역할을 찾아 책임을 할당한다. +- 객체가 책임을 수행하는 도중 다른 객체의 도움이 필요한 경우 이를 책임질 적절한 객체 또는 역할을 찾는다. +- 해당 객체 또는 역할에게 책임을 할당함으로써 두 객체가 협력하게 한다. +#### 메시지가 객체를 결정 +- 객체가 최소한의 인터페이스를 가질 수 있게 된다. +- 객체는 충분히 추상적인 인터페이스를 가질 수 있게 된다. +- 객체가 충분히 추상적이면서 미니멀리즘을 따르는 인터페이스를 가지게 하고 싶다면 메시지가 객체를 선택하게 하자. + +### 협력 +협력은 객체지향 세계에서 기능을 구현할 수 있는 유일한 방법이다. 두 개개체 사이의 협력은 하나의 객체가 다른 객체에게 도움을 할 때 시작된다. **메시지 전송**은 객체 사이의 협력을 위해 사용할 수 있는 유일한 커뮤니케이션 수단이다. + +객체가 객체에게 무언가를 요청하는 것이고 다른 객체가 필요할 때 위임하거나 협력한다. + +- 어떤 객체가 다른 객체에게 무엇인가를 요청하는 것 +- 한 객체는 어떤 것이 필요할 때 다른 객체에게 전적으로 위임하거나 서로 협력한다. +- 두 객체가 상호작용을 통해 더 큰 책임을 수행하는 것이다. +- 협력이 설계를 위한 문맥을 결정한다. +- 상태는 객체가 행동하는 데 필요한 정보에 의해 결정되고, 행동은 협력 안에서 객체가 처리할 메시지로 결정된다. +- 따라서 협력은 객체를 설계하는 데 필요한 일종의 문맥(context)를 제공한다. + + +객체 지향 프로그래밍에서 객체는 하나의 책임을 가진 역할로서 협력에 참여하여 소프트웨어의 목적을 달성한다. + +책임은 메시지보다 더 큰 개념으로 객체가 직접 수행하는 행동들에 대한 추상적이고 응집도 있는 집합이라고 할 수 있다. 개발을 할 때는 아래와 같이 협력 관계를 먼저 파악하고 필요한 책임들을 추린 뒤, 역할별로 객체를 설계하면 된다. 객체의 상태(데이터)를 기반으로 설계하는 것은 올바른 역할을 추리지 못할 가능성이 높다. + +## 메시지와 행동 + +### 메시지가 객체를 결정한다. +메시지가 객체를 선택해야 하는 이유는 아래와 같다. + +- 객체가 최소한 인터페이스를 가질 수 있게 된다.(필요한 크기의 퍼블릭 인터페이스를 가질 수 있음) +- 객체는 충분히 추상적인 인터페이스를 가질 수 있게 된다.(외부 객체가 요청하는 무언가를 의미하기 때문에 메시지를 먼저 식별하면 무엇을 수행할지에 초점을 맞추는 인터페이스를 얻을 수 있다.) + +### 행동이 상태를 결정한다. +개체의 내부 구현에 초점을 맞춘 설계 방법을 데이터 주도 설계라 부르기도 했다. 캡슐화를 위반하지 않도록 구현에 대한 결정을 뒤로 미루면서 객체의 행위를 고려하기 위해서는 항상 협력이라는 문맥 안에서 객체를 생각해야 한다.(얻고 제공하는 것) + + +## DTO(Data Transfer Object) +데이터가 포함된 객체를 한 시스템에서 다른 시스템으로 전달하는 작업을 처리하는 객체이다. (레이어 간의 통신용도로 오가는 객체를 DTO라 하고, 특정한 비즈니스 값을 담는 객체를 VO라 한다.) + + +데이터를 오브젝트로 변환하는 객체이다.(주체가 누구인가를 아는 것이 중요하다) + +DTO에서 Object는 우리가 만드는 DTO클래스이다. 아래는 PersonDTO 예시이다. +```java +class PersonDTO + private String name; + private int age; + + public void setName(String name){ + this.name = name; + } + + public String getName(){ + return this.name; + } + + public void setAge(int age){ + this.age = age; + } + + public int getAge(){ + return this.age; + } +} +``` + +위 클래스에는 getter와 setter(name, age필드에 데이터를 읽고 쓰는 역할)가 존재한다. getter와 setter에서 get과 set이후에 나오는 단어(혹은 단어들)을 property라고 해보자. 즉, 위 클래스에서 name과 age를 property라 가정하는 것이다. + +여기서 property는 멤버변수 name, age로 결정 되는 것이 아닌 getter, setter에서의 name과 age이다. 멤버변수의 변수명은 아무렇게나 지어도 영향이 없고 getter, setter로 property를 표현한다는 것이다.
+ +자바는 다양한 프레임 워크에서 데이터 자동화 처리를 위해 리플렉션 기법을 사용한다. 데이터 자동화 처리에서 가장 중요한 것은 표준규격이다. 예로, 위 클래스 DTO에서 property가 name, age라면 name, age의 키 값으로 들어온 데이터는 리플렉션 기법으로 setter를 실행시켜 데이터를 넣을 수 있다. + +우리가 setter를 요청하는 것이 아닌, 우리 눈에 보이지 않는 프레임워크단에서 setter가 실행된다. 데이터가 자동으로 클래스화가 되기 때문에 layer간에 데이터를 넘길 때 DTO를 사용하면 편하다. + +예로, form에서 name필드 값을 property에 맞춰서 값을 다른 페이지로 넘겼을 때, 값을 받아야할 페이지에서는 값을 하나씩 일일이 받는 것이 아니라 name 속성의 이름과 매칭 되는 property에 자동적으로 DTO가 인스턴스화 되어 PersonDTO를 자료형으로 값을 받을 수 있다는 것이다. 즉, key & value로 존재하는 데이터는 자동화처리된 DTO로 변환되어 우리는 손쉽게 데이터가 세팅된 오브젝트를 받을 수 있다. + +## VO(Value Object) +- 필요성: network traffic 감소 +- 장점: 비 서버 측 클라이언트도 네트워크 오버헤드 없이 영속성 데이터에 엑세스 할 수 있다. 데이터 전달을 위해 가장 효율적인 방법이다. +- 단점: 클래스의 선언을 위해 많은 코드가 필요하다. 따라서 파일 수가 많아지고 관리도 힘들다. + + +간단히 말하면 값을 위해 쓴다. 자바는 값 타입을 표현하기 위해 불변 클래스를 만들어 사용한다. (불변 클래스는 readOnly 특징을 가진다. 예로, String, Integer, Color 클래스가 있다.) 이런 클래스는 중간에 값을 바꿀 수 없고 새로 만들어야 한다. (Color클래스의 경우 Red라는 값을 표현하기 위해 Color.RED처럼 호출했을 때 값을 표현하기 위해 getter 기능만이 존재한다.) + + +## VO와 DTO의 비교 +DTO는 메소드 호출 횟수를 줄이기 위한 데이터를 담고 있는 것이고, VO는 값이 같으면 동일 오브젝트라고 볼 수 있는 것이라고 보통 표현한다. + +```java +DTO a = new DTO(1); +DTO b = new DTO(1); +// a != b +``` + +```java +VO a = VO(1); +VO b = VO(1); +// a == b +``` + + + +## 역할, 책임,협력(객체지향의 사실과 오해)->제일중요한 것은 메시지다. + +## vo(value object) + +## 문자열 계산기(프로그래밍 과제 1) + + +# 자바 기초 + +### 학습할 것 +- 산술 연산자 +- 비트 연산자 +- 관계 연산자 +- 논리 연산자 +- instanceof +- aggignment operator(=) +- 화살표 연산자(->) +- 3항 연산자 +- 연산자 우선 순위 +- (optional) Java 13. swithch operator + + +# Reference +- [역할, 책임, 협력 1](https://velog.io/@ljinsk3/%EC%97%AD%ED%95%A0-%EC%B1%85%EC%9E%84-%ED%98%91%EB%A0%A5) +- [역할, 책임, 협력 2](https://namget.tistory.com/entry/%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8-%EC%97%AD%ED%95%A0-%EC%B1%85%EC%9E%84-%ED%98%91%EB%A0%A5) +- [DTO와 VO란?](https://mommoo.tistory.com/61) +- [DTO, VO 차이점](https://itmore.tistory.com/entry/%EC%9E%90%EB%B0%94-VO-DTO-%EC%B0%A8%EC%9D%B4%EC%A0%90%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EB%B0%A9%EC%8B%9D%EC%9D%B4-%EA%B0%99%EB%8B%A4%EA%B3%A0-%EB%98%91%EA%B0%99%EB%8B%A4%EA%B3%A0-%EC%83%9D%EA%B0%81%ED%95%98%EC%A7%80-%EB%A7%90%EC%9E%90) \ No newline at end of file diff --git a/4weeks/2.java basics.md b/4weeks/2.java basics.md new file mode 100644 index 00000000..4762dbeb --- /dev/null +++ b/4weeks/2.java basics.md @@ -0,0 +1,412 @@ +# 자바 기초 + +## 산술(Arithmetic) 연산자 +수학적인 계산에 사용되는 연산자다. +| 수식 | 연산 | +|:---:|:---:| +| + | 더하기 | +| - | 빼기 | +| * | 곱하기 | +| / | 나누기 | +| % | 나머지 | + +## 비트(Shift) 연산자 +비트 연산자는 데이터를 비트 단위로 연산한다. 따라서 0과 1로 표현 가능한 **정수**타입이나 정수형으로 **캐스팅이 가능한**자료형만 비트 연산이 가능하다. 비트 연산자는 기능에 따라 아래와 같이 나뉜다. +- 비트 이동 연산자 +- 비트 논리 연산자 + +### 비트 이동 연산자 +| 연산식 | 설명 | +|:---:|:---:| +| x << y | 정수 x의 각 비트를 y만큼 왼쪽으로 이동시킨다. 빈 자리는 0으로 채워진다. | +| x >> y | 정수 x의 각 비트를 y만큼 오른쪽으로 이동시킨다. 빈 자리는 정수 a(x?)의 최상위 부호비트와 같은 값으로 채워진다. | +| x >>> y | 정수 x의 각 비트를 y만큼 오른쪽으로 이동시킨다. 빈 자리는 0으로 채워진다. | + +#### 2 << 3 +![2<<3](https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCkFTP%2FbtqDliWFHTr%2FKD08H1foVnhVhvZcUvKcq1%2Fimg.png) + +#### 16 >> 3 +![16>>3](https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqOvM1%2FbtqDj2AcdBR%2FJm2hw2X8V3QPH6kpdhOsx0%2Fimg.png) + +#### -16 >> 3 +![-16 >> 3](https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FekMbBV%2FbtqDk6IXvz7%2F8tEH93tlmA0oUQFmZjg3I0%2Fimg.png) + +#### -16 >>> 3 +![-16 >>> 3](https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPZrk3%2FbtqDlO19CFf%2FCBLZG7ta3NscZS79mFqeG0%2Fimg.png) + + +### 비트 논리 연산자 +| 연산자 | 논리 | 설명 | +|:---:|:---:|:---:| +| & | AND | 두 비트 모두 1일 경우에만 연산 결과가 1 | +| \| | OR | 두 비트 중 하나만 1일 경우에만 연산결과가 1 | +| ^ | XOR | 두 비트 중 하나는 1이고 다른 하나가 0일 경우에만 연산결과가 1 | +| ~ | NOT | 비트 반전(보수) | + + +## 관계(relational) 연산자 + +비교 연산자라고도 한다. 관계 연산자의 결과는 boolean 자료형인 true, false로 반환된다.(제어문에서 많이 활용) + +| 연산자 | 기능 | +|:---:|:---:| +| > | 좌항이 크면 참, 아니면 거짓을 반환 | +| < | 좌항이 작으면 참, 아니면 거짓을 반환 | +| >= | 좌항이 우항보다 크거나 같으면 참, 아니면 거짓을 반환 | +| <= | 좌항이 우항보다 작거나 같으면 참, 아니면 거짓을 반환 | +| == | 두 항의 값이 같으면 참, 아니면 거짓을 반환 | +| != | 두 항이 다르면 참, 아니면 거짓을 반환 | + + +## 논리(logical) 연산자 + +연산의 결과가 true, false로 반환된다. +| 연산자 | 기능 | +|:---:|:---:| +| &&(논리 곱) | 두 항이 모두 참인 경우에만 결과 값이 참이다. 그렇지 않은 경우는 거짓이다. | +| \|\|(논리 합) | 두 항 중 하나의 항만 참이면 결과 값이 참이다. 두 항이 모두 거짓이면 거짓이다. | +| !(부정) | 단항 연산자이다. 참인 경우는 거짓으로 바꾸고, 거짓인 경우는 참으로 바꾼다. | + + +## 3항 연산자 +다양한 삼항 연산자가 있지만 조건 연산자(?:)는 상당히 흔한 반면 다른 삼항 연산자는 잘 쓰지 않아서, 흔히 조건 연산자를 삼항 연산자라고 부른다. + +> 조건 연산자(condition operator), 인라인 조건문(inline if), 삼항 조건문(ternary if)라고 불린다. + + +- 문(statement), 식(expression)의 구분 +> 식은 값을 만들어 내며 다른 식의 하위 요소로 계산에 참여할 수 있는 반면 문은 자신을 둘러싸고 있는 가장 안쪽 블록의 최상위 요소로 존재하며 아무런 값을 만들어내지 않는다는 차이가 있다. + +```java +condition ? A : B +// condition의 결과가 true일 때 A 반환. +``` + +### if/else 와의 차이점 + +- if/else - 문(statement). if자체로는 값을 만들어내지 못한다. +- 조건 연산자 - 식(expression). 값을 만들어낸다. + +```java +String message = String.format("%d와 %d중 더 큰 수는 %d입니다.", a, b, (a > b) ? a : b); +``` + +## 화살표 연산자(arrow operator) +(C언어) + +보통 구조체에 접근할 때 포인터를 통해 접근한다. + +```C +struct s_type { + int i; + char str[80]; +} s, *p; +``` + +위와 같이 정의된 경우, 다음 문장은 s의 주소를 p에 치환한다. +> p = &s; + +p가 s를 가리키고 있으므로, p를 통하여 s에 접근할 수 있다. 그러나 p를 이용하여 s의 각 원소를 접근하기 위해, 도트 연산자 dot operator를 사용할 수 없다. + +아래와 같이 화살표 연산자 arrow operator를 사용해야 한다. + +> p -> i = 1; + +이 문장은 p를 통해 s의 원소 i에 값 1을 치환한다. + +- 구조체 변수를 이용해 구조체 원소에 접근할 때, 도트 연산자 +- 포인터를 이용해 구조체 원소에 접근할 때, 화살표 연산자 + + +## 람다 표현식(lambda expression) +메소드를 하나의 식으로 표현한 것이다. +```java +// 메소드 +int min(int x, int y) { + return (x < y) ? x : y; +} + + +// 람다 표현식 +(x, y) -> (x < y) ? x : y; + + +// 익명 클래스 +new Object() { + int min(int x, int y) { + return (x < y) ? x : y; + } +} +``` + +위처럼 메소드를 람다 표현식으로 쓰면 클래스를 작성하고 객체를 생성하지 않아도 메소드를 사용할 수 있다. + +자바에서는 클래스의 선언과 동시에 객체를 생성한다. 단 하나의 객체만을 생성할 수 있는 클래스를 익명 클래스라 한다. 따라서 자바에서 람다 표현식은 익명 클래스와 같다. + +이런 람다 표현식은 메소드의 매개변수로 전달될 수도 있고 메소드의 결과값으로 반환될 수도 있다. + + +### 람다 표현식 유의사항 +1. 매개변수의 타입을 추론할 수 있는 경우에는 타입을 생략할 수 있습니다. +2. 매개변수가 하나인 경우에는 괄호(())를 생략할 수 있습니다. +3. 함수의 몸체가 하나의 명령문만으로 이루어진 경우에는 중괄호({})를 생략할 수 있습니다. (이때 세미콜론(;)은 붙이지 않음) +4. 함수의 몸체가 하나의 return 문으로만 이루어진 경우에는 중괄호({})를 생략할 수 없습니다. +5. return 문 대신 표현식을 사용할 수 있으며, 이때 반환값은 표현식의 결괏값이 됩니다. (이때 세미콜론(;)은 붙이지 않음) + +```java +new Thread(new Runnable() { + + public void run() { + + System.out.println("전통적인 방식의 일회용 스레드 생성"); + + } + +}).start(); + + + +new Thread(()->{ + + System.out.println("람다 표현식을 사용한 일회용 스레드 생성"); + +}).start(); +``` + + +## 대입(assignment) 연산자 + +대입 연산자는 변수에 값을 대입할 때 사용하는 이항 연산자이며, 피연산자들의 결합 방향은 오른쪽에서 왼쪽이다. 아래는 대입 연산자와 복합 대입 연산자이다. + +| 대입 연산자 | 설명 | +|:---:|:---:| +| = | 좌항에 우항을 대입함 | +| += | 좌항에 우항을 더한 후, 그 결괏값을 좌항에 대입함 | +| -= | 좌항에서 우항을 뺀 후, 그 결괏값을 좌항에 대입함 | +| *= | 좌항에 우항을 곱한 후, 그 결괏값을 좌항에 대입함 | +| /= | 좌항을 우항으로 나눈 후, 그 결괏값을 좌항에 대입함 | +|%= |좌항을 우항으로 나눈 후, 그 나머지를 좌항에 대입함 | +| &= | 좌항을 우항와 비트 AND 연산한 후, 그 결괏값을 좌항에 대입함 | +| \|= | 좌항을 우항와 비트 OR 연산한 후, 그 결괏값을 좌항에 대입함 | +| ^= | 좌항을 우항와 비트 XOR 연산한 후, 그 결괏값을 좌항에 대입함 | +| <<= | 좌항을 우항만큼 왼쪽 시프트한 후, 그 결괏값을 좌항에 대입함 | +| >>= | 좌항을 우항만큼 부호를 유지하며 오른쪽 시프트한 후, 그 결괏값을 좌항에 대입함 | +| >>>= | 좌항을 우항만큼 부호에 상관없이 오른쪽 시프트한 후, 그 결괏값을 좌항에 대입함 | + +```java +int num1 = 7, num2 = 7, num3 = 7; + +num1 = num1 - 3; +num2 -= 3; +num3 =- 3;// 순서 참고 + +System.out.println("- 연산자에 의한 결과 : "+ num1); +// 4 +System.out.println("-= 연산자에 의한 결과 : "+ num2); +// 4 +System.out.println("=- 연산자에 의한 결과 : "+ num3); +// -3 +``` + + +## 연산자 우선 순위 + +### 우선 순위 +- 괄호 > 산술 > 비교 > 논리 > 대입 +- 단항 > 이항 > 삼항 + +### 연산 진행방향 +- 왼쪽에서 오른쪽: 단항 연산자, 대입 연산자 +- 오른쪽에서 왼쪽: 위 두 개를 제외한 연산자 + +### 기본 연산자 우선 순위 +![operator order](https://t1.daumcdn.net/cfile/tistory/997A014D5A90B9B00D) + + +## instanceof +레퍼런스 변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위해 사용한다. 주로 주건문에 사용되며, instanceof의 왼쪽에는 레퍼런스 변수를 오른족에서 타입(클래스 명)이 피연산자로 위치한다. + +instanceof를 이용한 연산결과로 true를 얻었다면 레퍼런스 변수가 검사한 타입으로 형변환이 가능하다는 것을 뜻한다. + +연산의 결과로 boolean값인 true, false중 하나를 반환한다. 값이 null인 참조변수에 대해 instanceof 연산을 수행하면 false를 반환한다. + +```java +package arabiannight.tistory.com.java.test; + +public class Instanceof { + public static void main(String[] args) { + FireEngine f = new FireEngine(); + Ambulance a = new Ambulance(); + + Instanceof test = new Instanceof(); + test.doWork(f); + test.doWork(a); + } + + public void doWork(Car c) { + if (c instanceof FireEngine) { + FireEngine f = (FireEngine) c; + f.water(); + } else if (c instanceof Ambulance) { + Ambulance a = (Ambulance) c; + a.siren(); + } + } +} + +class Car { + String color; + int door; + + void drive() {// 운전기능 + System.out.println("drive, brrr"); + } + + void stop() { + System.out.println("stop!"); + } +} + +class FireEngine extends Car { + void water() { + System.out.println("water!"); + } +} + +class Ambulance extends Car { + void siren() { + System.out.println("siren~~"); + } +} + +``` + +위의 코드는 Car타입의 참조변수 c를 매개변수로 하는 메소드이다. 이 메소드가 호출될 때, 매개변수로 Car클래스 또는 그 자손 클래스의 인스턴스를 넘겨받겠지만 메소드 내에서는 정확히 어떤 인스턴스인지 알 길이 없습니다. 그렇기 때문에 instanceof 연산자를 이용해서 참조변수 c가 가리키고 있는 인스턴스의 타입을 체크하고, 적절히 형변환한 다음에 작업한다. + +조상타입의 레퍼런스 변수로 자손타입의 인스턴스를 참조할 수 있기 때문에, 레퍼런스 변수의 타입과 인스턴스의 타입이 항상 일치하지는 않는 것이다. 조상타입의 레퍼런스 변수로는 실제 인스턴스 멤버들을 모두 사용할 수 없기 때문에, 실제 인스턴스와 같은 타입의 참조변수로 형변환을 해야만 인스턴스의 모든 멤버들을 사용할 수 있다. + +```java +package arbiannight.tistory.com.java.test; + +import java.awt.*; + +class InstanceofTest { + public static void main(String[] args) { + FireEngine f = new FireEngine(); + + if (f instanceof FireEngine) { + System.out.println("This is a FireEngine istance."); + } + if (f instanceof Car) { + System.out.println("This is a Car instance."); + } + if (f instanceof Object) { + System.out.println("This is an Object instance."); + } + } +}// class +class Car{} +class FireEngine extends Car{} +``` + +생성된 인스턴스는 FireEngine타입이지만 Object타입과 Car타입의 instanceof 연산에서도 true를 결과로 얻었습니다. 그 이유는 FireEngine클래스는 Object클래스와 Car클래스의 자손클래스이므로 조상의 멤버들을 상속받았기 때문에, FireEngine인스턴스는 Object인스턴스와 Car인스턴스를 포함하고 있는 셈이기 때문이다. + +즉, 실제 인스턴스와 같은 타입의 instanceof연산 이외의 조상타입의 instanceof 연산에도 true를 결과로 얻으며, instanceof 연산의 결과가 true라는 것은 검사한 타입으로의 형변환을 해도 아무런 문제가 없다는 것이다. + +### 정리 +- 인스턴스 멤버보다 참조변수가 사용할 수 있는 멤버수가 더 많으면 사용할 수 없다. +- 인스턴스 멤버 수에 비해 참조변수가 사용할 수 있는 멤버수가 같거나 적은 경우 사용할 수 있다. + +그러므로 조상의 레퍼런스로는 모든 자손의 인스턴스를 참조할 수 있다. + + +## switch 연산자 +기존의 switch문이 변경된 것이 아니라 switch연산자가 추가된 것이다. + + +### swtich statement, switch operator +- switch statement +> 다수의 case, break가 존재한다.
+> break;를 빼먹을 경우 다음 분기로 넘어가게 된다.
+> return 값이 존재할 수 없다. + + +- switch operator +> break를 사용하지 않아도 된다.
+> yield 존재한다.
+> return 값이 존재할 수 있다.
+> case -> A같은 형식으로 표현가능하다. + + +switch의 반환값이 따로 필요하지 않거나 case가 switch 들어오는 모든 인자를 커버하는 경우 default 항목을 넣어주지 않아도 되나 그렇지 않은 경우는 default -> code를 작성해야 한다. + + +### java12와 java13에 추가된 기능 +- java 12 + - 화살표(->) 표현이 가능하고 data만 존재할 경우 return이 가능하다. + - 화살표 구문을 사용할 경우 break;를 적지 않아도 다음 case 구문으로 넘어가지 않는다. + - 화살표 표현 오른쪽은 꼭 단일 수행일 필요는 없다. 블록({}) 안에서의 작업도 가능하다. + + +- java 13 + - yield 예약어가 추가되었다. yield x 하게 되면 x가 리턴된다. + - yield는 예약어이지만 변수명으로 사용가능하다. (int yield = 0;) + + + +```java +public class Main { + public static void main(String[] args) { + + //Java 12 이전 + int num = 1; + int returnNum = 0; + switch(num){ + case 1: + returnNum = 1; + System.out.println("1들어옴"); + break; + case 2: + returnNum = 2; + System.out.println("2들어옴"); + break; + case 3: + returnNum = 3; + System.out.println("3들어옴"); + break; + } + System.out.println("returnNum : [ " + returnNum + " ]"); + + //Java 12 + returnNum = switch(num){ + case 1 -> 1; + case 2 -> 2; + default -> throw new IllegalStateException("Unexpected value: " + num); + }; + System.out.println("returnNum : [ " + returnNum + " ]"); + + + //Java13 + returnNum = switch(num){ + case 1 : yield 3; + default : throw new IllegalStateException("unexpected value : " + num); + }; + + System.out.println("returnNum : [ " + returnNum + " ]"); + + } +} + + +1들어옴 +returnNum : [ 1 ] +returnNum : [ 1 ] +returnNum : [ 3 ] +``` + + +# Reference +- [Shift operator](https://coding-factory.tistory.com/521) +- [lambda expr](http://www.tcpschool.com/java/java_lambda_concept) +- [instanceof operator](https://arabiannight.tistory.com/313) +- [switch operator](https://castleone.tistory.com/6) \ No newline at end of file diff --git a/4weeks/stringCalc/src/main/java/CalculateNum.java b/4weeks/stringCalc/src/main/java/CalculateNum.java new file mode 100644 index 00000000..492cdf98 --- /dev/null +++ b/4weeks/stringCalc/src/main/java/CalculateNum.java @@ -0,0 +1,23 @@ +public class CalculateNum { + public static double addNum(double a, double b) { + return a + b; + } + + public static double subNum(double a, double b) { + return a - b; + } + + public static double mulNum(double a, double b) { + return a * b; + } + + public static double divNum(int a, int b) { + try { + return a / b; + } + catch(ArithmeticException e){// 0으로 나눌 경우 + System.out.println("0으로 나눌 수 없습니다."); + return 0; + } + } +} diff --git a/4weeks/stringCalc/src/main/java/Calculator.java b/4weeks/stringCalc/src/main/java/Calculator.java new file mode 100644 index 00000000..1e554636 --- /dev/null +++ b/4weeks/stringCalc/src/main/java/Calculator.java @@ -0,0 +1,8 @@ +import java.io.IOException; + +public class Calculator { + public static void main(String[] args) throws IOException { + Input input = new Input(); + input.inputFormula(); + } +} \ No newline at end of file diff --git a/4weeks/stringCalc/src/main/java/Input.java b/4weeks/stringCalc/src/main/java/Input.java new file mode 100644 index 00000000..33b9e6bd --- /dev/null +++ b/4weeks/stringCalc/src/main/java/Input.java @@ -0,0 +1,36 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +public class Input { + private String[] arrayFormula; + private boolean isComputable = true; + + public void inputFormula() throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + this.arrayFormula = br.readLine().split(" ");// 공백을 기준으로 연산자, 피연산자 구분 후 배열에 삽입 + for (int i = 1; i < arrayFormula.length; i += 2) {// 피연산자 중 숫자가 아닌 것이 있을 경우 + if (isElementInt(arrayFormula[i - 1]) == false || isElementInt(arrayFormula[i + 1]) == false) { + isComputable = false; + break; + } + } + if (isComputable) {// 피연산자가 들어갈 부분에 모두 들어갔다면 연산 시작 + Performer performer = new Performer(arrayFormula); + performer.performCal(); + } + } + + // 숫자가 들어가는 부분에 숫자가 들어갔는지 확인 + private boolean isElementInt(String str) { + try{ + Integer.parseInt(str); + return true; + } + catch(IllegalArgumentException e){// 숫자로 변경이 불가한 경우 + System.out.println("입력된 값이 숫자가 아닙니다."); + return false; + } + } + +} diff --git a/4weeks/stringCalc/src/main/java/Performer.java b/4weeks/stringCalc/src/main/java/Performer.java new file mode 100644 index 00000000..276cd4bb --- /dev/null +++ b/4weeks/stringCalc/src/main/java/Performer.java @@ -0,0 +1,32 @@ +public class Performer { + private static String[] formula; + private static double result = 0;// 연산 도중 값을 저장하고 최후에 결과값을 저장함 + + public Performer() {} + public Performer(String[] formula) {// 생성자. 인스턴스 생성과 동시에 formula 값 세팅 + this.formula = formula; + } + + public static void performCal(){// 계산수행 + for (int operator = 1; operator < formula.length; operator += 2) { + if (formula[operator].equals("+")) { + result = CalculateNum.addNum(Double.parseDouble(formula[operator - 1]), + Double.parseDouble(formula[operator + 1]));// 연산에서 누락되는 것을 줄이기 위해 double + } + if (formula[operator].equals("-")) { + result = CalculateNum.subNum(Double.parseDouble(formula[operator - 1]), + Double.parseDouble(formula[operator + 1])); + } + if (formula[operator].equals("*")) { + result = CalculateNum.mulNum(Double.parseDouble(formula[operator - 1]), + Double.parseDouble(formula[operator + 1])); + } + if (formula[operator].equals("/")) { + result = CalculateNum.divNum(Integer.parseInt(formula[operator - 1]), + Integer.parseInt(formula[operator + 1])); + } + formula[operator + 1] = Double.toString(result);// 연산자 1개, 피연산자 2개가 아닐경우 연산을 계속 진행 + } + System.out.println("computed value : " + (int)result);// 형식을 맞추기 위해 정수형으로 캐스팅 + } +}