-chapter8은 메모장과 명령프롬프트를 이용한다.-



<1> 클래스 패스(class path)의 지정 

 - 클래스 패스 : 클래스의 경로 (클래스가 존재하는 경로) 프로그램의 실행과정에서 클래스를 찾을 때 클래스패스를 기준으로 찾음. 


 1. 컴파일된 클래스 파일의 위치를 이동시킵시다 

1) myclass라는 디렉토리(폴더) 만들기. 

2) 다음의 .java 파일 작성해서 myclass 디렉토리 안에 저장하기



3) 명령프롬프트 (cmd.exe) 로 컴파일 한 후 myclass 디렉터리 안을 확인하면 다음과 같다.



4) 실행 후 결과.



5) myclass 안에 mysubclass 라는 서브디렉토리를 만들어 그 안에 AAA.class 와 BBB. class 파일을 넣는다



6) 다시 ClassPath.java 파일을 실행한 결과! 




: ClassPath.class 는 실행되는 디렉토리에 존재하니 이 파일은 쉽게 찾을수 있다. 문제는 AAA.class, BBB.class. 

기본적으로 아무 설정도 하지 않으면 java.exe가 실행된 디렉터리에서만 가상머신에 올려질 클래스를 찾는다. 


-> "java.exe 를 실행한 현재 디렉터리의 서브 디렉토리인 mysubclass 디렉터리에서 클래스를 찾아보세요" 라는 메세지를 전달해야 한다. 


*명령프롬프트가 위치하는 현재 디렉터리 : cd 커맨드를 이용해서 이동하는 위치 

바로 위의 에러 사진에서는 C:\java\myclass> 라고 써 있기 때문에 명령 프롬프트의 현재 위치는 C:\java\myclass 이다. 


2. 환경변수 (Environment Variable) :

1) 계산기와 파일탐색기의 실행 





: 계산기 (calc.exe) 와 파일탐색기 (explorer.exe)가 명령프롬프트의 현재 위치 (C:\java\myclass) 안에 있지 않지만 실행된다. 


2) 다른프로그램의 실행 능력을 지니는 명령프롬프트는 환경변수 path를 참조하여 실행파일의 위치를 참색한다. 

- 환경변수 : 명령프롬프트상에서 프로그램을 실행할 때 해당 프로그램의 실행파일을 찾는 경로, 환경변수에 포함되면 현재 위치가 어디든 실행할 수 있다. 

- echo %path%로 환경변수 찾기 (echo : 출력 , %path% : 환경변수) : 환경변수 parh에 지정된 정보(문자열형태) 확인

 : 엄청 많은 결과. 세미콜론으로 각각의 데이터들이 구분된다. 


- 저 환경변수에는 

. : 현재 디렉터리

C:\WINDOWS\system32 : 계산기, 탐색기가 있는 디렉터리

C:\Program Files\java\jdk1.8.0_121\bin : javac.exe , java.exe가 있는 디렉터리 

이 들어있음. 



3. 환경변수에 classpath 설정하기

: 환경변수는 path 하나만 존재하는 것 x. 필요에 따라서 얼마든지 추가할 수 있다. 

java는 클래스의 검색 경로를 지정할 수 있도록 classpath라는 환경변수 정의  

-> 클래스의 경로정보를 classpath라는 환경변수에 추가함으로 인해 클래스의 검색 경로 확장 가능. 


1) classpath에 설정되어있는 문자열 정보 확인  : echo %classpath%

- 아무런 classpath도 설정되어 있지 않을때의 결과

- 환경변수 추가하기 - 현재 디렉터리(.) : set classpath=,;


↓ 클래스패스 추가와 확인 

*이런과정을 거치지 않아도 원래 현재 디렉터리는 기본적인 클래스파일의 탐색경로에 포함된다. 




4. 문제해결을 위한 classpath의 설정 : 이전에 했던 classpath.java 실행하기  

1) 이전(classpath.java)의 실행 : myclass의 서브디렉토리인 mysubclass 디렉토리 안의 AAA.class와 BBB.class를 찾지 못해 오류. 

-> mysubclass 디렉터리를 classpath에 추가해야 한다. 


2) classpath추가 방법 1. 드라이브 명을 포함하는 완전경로 지정하기 

set classpath = .;C\java\myclass\mysubclass; 

(하는 사람마다 다르다. 각자의 경로를 써야함 -절대경로)



3) classpath추가 방법 2. 상대경로로 지정하기 


set classpath=.;.\mysubclass;



(** '.' : 현재위치 , '\' : 자식폴더 , '..' : 부모폴더)




5.  





코드를 다 작성하고 실행할 때 저런 에러가 생길 수 있다 


해결방안 

1. 메인 함수가 public static void main(String[] args) 가 맞나 확인한다.

2. 현재 작성하고 있는 파일이 src 폴더 안에 들어가있는지 확인한다. 

<2> 생성자 (Constructor)


1. 두 명의 과일장수와 한 명의 구매자  

1) 과일장수1 : 보유하고 있는 사과의 수 30개, 개당 가격은 1500원

   과일장수2 : 보유하고 있는 사과의 수 20개, 개당 가격은 1000원

인 두명의 과일장수에서 '나' 가 

"나는 과일장수1에게 4500원어치 사과를 구매했고, 과일장수2에게 2000원어치 사과를 구매했다" 를 실행할 예정 

2) 문제점 : 두 개의 과일장수 인스턴스를 생성해야 하고 과일장수의 사과 보유 수 및 가격이 다르기 때문에 인스턴스 변수의 초기값도 달라져야 함 

- > 인스턴스를 생성 하고 나서 인스턴스 변수 초기화. : FruitSeller class에  인스턴스 변수를 초기화 하는 initMember 메소드를 넣었다.  




//참조변수 seller1과 seller2는 다르다! 같은 class 에서 각기 다른 주소에 각기 다른 객체 생성, 그 주소를 넘겨주는 것.

//FruitSeller seller1 = new FruitSeller(); 

 FruitSeller seller2=seller1; 

 와 다르다  


: 이 코드의 문제점 

- 인스턴스를 생성하고 난 다음에 또 변수를 초기화 하기 때문에 2줄에 걸쳐서 문장을 구성해야 한다. 

(많은 인스턴스가 생성되면 큰 문제점이 될 수 있음)

-FruitSeller 클래스의 인스턴스변수 APPLE_PRICE의 final선언이 없어짐. 


-> 프로그래머가 실수로 final선언하지 못한 변수를 수정할 시에 치명적인 문제가 생길 수 있다   

(메소드는 여러번 사용할수 있기 때문에 메소드 안에 final 변수는 초기화가 불가능하다.)


↓ 해결방안


2. 생성자(constructor)  

: 딱 한번만 호출되는 메소드, 인스턴스변수의 초기화를 위해 정의됨. (final변수 선언 가능)





1) 생성자가 되기 위한 조건 : 

- 클래스와 동일한 이름의 메소드

- 반환형이 선언되어 있지 않으면서, 반환하지 않는 메소드


2) 인스턴스가 생성될 때 마다 생성자가 호출되어야 한다. : 생성자는 딱 한번 호출된다. 

- New Number : Number의 인스턴스 생성 

- Number(); : Number() 생성자 호출  



3. 생성자의 정의

1) 생성자는 다른 메소드들과 같이 값을 전달받을 수 있다. 받는형태도 자유


: 생성자를 사용하면 인스턴스 변수의 초기화를 한결 수월하게 진행할 수 있다! 



4. 코드의 개선

내가 생성자를 사용해서 해본 것



- 책에 나온 코드 : FruitBuyer 클래스에서도 생성자를 사용했다  





5. 생성자가 없어도 인스턴스 생성이 가능한 이유 : 디폴트 생성자(Default Constructor)

지난 게시물의 사과장수코드에서는 생성자가 정의되어 있지 않음에도 불구하고 FruitSeller seller=new Fruitseller(); 등등을 통해 인스턴스 생성 및 생성자 호출을 하였다. 그리고 인스턴스 생성과정에서는 반드시 생성자가 호출되어야 하는데 오류가 나지 않았던 이유 : 디폴트 생성자 


1) 디폴트 생성자 : 프로그래머가 클래스 안에 생성자메소드를 삽입하지 않으면 자바컴파일러가 자동으로 삽입해 주는 생성자. 

예시 ) FruitSeller의 디폴트 생성자 

public FruitSeller() 

{

// 텅 비어있다! 


}


* 디폴트생성자는 public 일수도 있고 아닐수도 있다 -이후에 공부 




<3> 자바의 이름 규칙 (Naming rule) : 문법과 관계는 없지만 다른 사람에게 보여주거나 다른 사람의 것을 볼 때 사용하는게 유용하다 (관례적인 표현)


1. 클래스의 이름 규칙 : 'Camel Case'

1) 첫문자는 대문자

2) 둘 이상의 단어가 묶여서 하나의 이름을 구성할 때 새로 시작하는 단어는 대문자

ex ) circle point -> CirclePoint


2. 메소드와 변수의 이름 규칙 : 클래스와 구분되어야 한다. 변형된 Camel Case

- 첫 문자를 소문자 

ex ) addYourMoney, yourAge


3. 상수의 이름 규칙 : 구분이 되기 위해 모든 문자 대문자로 하는것이 관례 

final int COLOR=7;

+) 단어가 연결되어야 하는경우 언더바

final int COLOR_RAINBOW=7;




문제 1. 

아래의 문제에서 요구하는 클래스들을 정의하되, 위에서 설명한 Camel Case 이름 규칙을 적용하여 메소드와 변수, 클래스 이름 지어주기. 정의한 클래스 확인을 위한 main 메소드도 적절의 정의. 


Q1. 밑변과 높이 정보를 저장할 수 있는 Triangle 클래스 정의. 생성과 동시에 초기화가 가능한 생성자도 정의. 밑변과 높이 정보를 변경시킬수 있는 메소드와 삼각형의 넓이를 계산해서 반환하는 메소드도 함께 정의


내가 만들어본 코드 : 



책의 코드 : 변수 지정 간단하게, 밑변과 높이의 변경을 따로따로 했다. 중간에 확인하는 출력과정 없음 




Q2. 구슬치기 


다음 조건에 만족하는 클래스 정의 

- 어린아이가 소유하고 있는 구슬의 갯수 정보 담을 수 있다 

-놀이를 통한 구슬의 주고받음을 표현하는 메소드 존재

-어린이의 현재 보유자산(구슬의 수)을 출력하는 메소드 존재


두번째 조건은 두 아이가 구슬치기를 하는 과정에서 구슬을 잃고 얻음을 의미하는것. 위의 조건을 만족하는 클래스를 정의하였다면 다음 조건을 만족하는 인스턴스 각각 생성 

- 어린이1의 보유자산 : 구슬 15개

- 어린이2의 보유자산 : 구슬 9개


인스턴스의 생성이 완료되면 다음상황을 main메소드 내에서 시뮬레이션 

- 1차 게임에서는 어린이1은 어린이2의 구슬 2개 획득 

- 2차 게임에서는 어린이2는 어린이1의 구슬 7개 획득 


마지막으로 각각의 어린이가 보유하고 있는 구슬의 수 출력하면서 프로그램 종료. 


- 내가 만든 코드





- 책의 코드 : 진 어린이가 줘야 하는 구슬 수가 어린이가 가진 구슬 수보다 클 때의 경우가 있다. -단순 변경이 아닌 return 사용







 








<1> 클래스의 정의와 인스턴스 생성 : 완벽한 개체지향 언어 java

 

1. 객체지향 프로그래밍의 이해

1) 객체 (object) : 물건, 또는 대상

 

2) 객체지향 프로그래밍

example)

"나는 과일장수에게 두 개의 사과를 구매했다 ! " 에서

객체 : 나, 과일장수, 사과

액션 : 객체 '사과'의 구매, 객체 '사과'의 판매

-> 객체지향 프로그래밍에서는 객체(나, 과일장수)를 등장시킬 수 있을 뿐만 아니라 행위('나'라는 객체가 '과일장수'로부터 '사과'구매, '과일장수'가 '나'에게 '사과'판매) 도 그대로 표현할 수 있다.

 

- 객체지향 프로그래밍 : 현실에 존재하는 사물과 대상, 그리고 그에 따른 행동을 있는 그대로 실체화 시키는 형태의 프로그래밍

* 뒤의 내용부터 코드의 간결성을 위해 '사과'는 객체화 시키지 않는다.

 

 

 

2. 객체는 데이터와 기능으로 이루어진다.

1) 객체 과일장수 : "과일의 판매"

- 과일을 판다 행동(behavior)  

- 과일장수는 사과 20개, 오렌지 10개 보유 상태(state)

- 과일장수의 과일판매 수익은 50,000원 상태(state)

:

(1) 객체는 하나 이상의 상태 정보(데이터)와 하나 이상의 행동(기능)으로 구성

(2) 상태 정보는 변수를 통해서 표현(변수에 상태 정보를 저장할 수 있으므로), 행동은 메소드를 통해서 표현

 

2) 과일장수의 상태 정보 표현(변수) *사과만 판다고 가정

-보유하고 있는 사과의 수 -> int numOfApple;

-판매 수익 -> int myMoney;

 

3) 과일장수의 행위(과일판매) 표현 (메소드) *이 메소드 내에서 과일장수의 현재상태를 나타내는 위의 변수에 직접 접근 가능하다고 가정

 

int saleApple(int money) //사과 구매액이 메소드의 인자로 전달

{

int num=money/1000; //사과가 개당 1000원이라고 가정

numOfApple-=num; //사과의 수가 줄어들고

myMoney+=money; //판매 수익 발생

return num; //실제 발생한 사과의 수 반환

}

 

 ============↓ 이들을 묶어서 객체라는 것을 통해 실체화* ===================*

 

 

 

3. 클래스(class)라는 틀을 기반으로 객체 생성

: '나' 또는 '과일장수'로 객체를 생성하기 위해선 둘을 위한 틀을 만들어야 한다.

1) 틀 구성 방식

class FruitSeller

{

int numOfApple=20;

int myMoney=0;    //변수선언

 

public int SaleApple(int money)

{

int num = money/1000;

numOfApple-=num;

myMoney+=money;

return num;

}    //메소드 정의

}

 

2) 클래스 

-class FruitSeller : FruitSeller라는 이름의 틀 정의 , 틀 = 클래스(class)

 

3) 클래스의 구성 요소

-위 예제에서 2개의 변수, 하나의 메소드 : 클래스는 객체를 구성하는데 필요한 변수와 메소드로 구성

-메소드 내에서 동일한 클래스 안에 선언된 변수에 접근 가능

*static 키워드 삽입 x  (-> chpter10에서 배움)

 

 

 

---- "나는 과일자수에게 2000원을 주고 두 개의 사과를 구매했다" 시뮬레이션 하기 위해 필요한 클래스 정의-----**

;

4. '과일장수' 클래스 정의와 키워드 final 

- 과일장수 클래스에 추가 : "2,000원 벌었어, 남은 사과는 18개 이고 말이야!" 라고 말하는 행위

1) '과일장수' 클래스 정의 FruitSeller

 

class FruitSeller

{

final int APPLE_PRICE=1000;    //사과 가격

int numOfApple=20;

int myMoney=0;

 

public int saleApple(int money)

{

int num=money/APPLE_PRICE;

numOfApple-=num;

myMoney+=money;

return num;    //판매한 과일의 수 반환

}

public void showSaleResult()

{

System.out.println("남은 사과 : "+numOfApple);

System.out.println("판매 수익 : "+myMoney);

}

}

 

-showSaleResult 메소드 추가

-final int APPLE_PRICE=1000; 으로 사과 가격 추가

 

2) 키워드 final

- final 변수 : final 키워드 삽입 후 선언한 변수 (변수가 상수화 된것이기 때문에 final 상수라고도 한다)

- final 선언 : " 한번 값이 결정된 이 변수의 값은 변경이 불가능하다!" - 지역변수로 final이 선언되면 딱 한번 값의 초기화가 가능

- 선언과 동시에 초기화 아닌 선언만 하는 것 가능.

 

final int APPLE_PRICE;

 

-> 딱 한번 초기화 가능

 

APPLE_PRICE=1000;

 

 

5. '나(me)' 클래스 정의

1) 삽입할 변수 ('나'의 상태) : 돈, 물품  

-소유하고 있는 현금 -> int myMoney;

-소유하고 있는 사과의 수 -> int numOfApple;

 

2) 삽입할 메소드 ('나'의 행위) : 과일의 구매 -> buyApple의 메소드 정의

 

3) '나'의 클라스 정의 FruitBuyer

 

class FruitBuyer

{

int myMoney=5000;

int numOfApple=0;

 

public void buyApple(FruitSeller seller, int money)

{

numOfApple+=seller.saleApple(money);

myMoney-=money;

}

public void Result()

{

System.out.println("현재 잔액 : "+myMoney);

System.out.println("사과 개수 : "+numOfApple);

}

}

 

** 보라색으로 표시한 내용은 뒤에서 설명될 것이다

 

 

--------------------------------------------------------클래스 정의 끝--------------------------------------------------*

6. 클래스를 기반으로 객체 생성하기

" 위에서 정의한 클래스들은 '틀'에 불과하다. 따라서 접근도 호출도 불가능하다 "-> 정의한 클래스 실체화, 즉 객체화

 

↓ 자바에서 정의하고 있는 객체 생성방법

ClassName name = new ClassName();

 

FruitSeller클래스와 FruitBuyer클래스 객체 생성방식 :

FruitSeller seller = new FruitSeller();

FruitBuyer buyer = new FruitBuyer():

 

1) 대입 연산자의 오른편 new FruitSeller(); / new FruitBuyer();

(1) new : 객체생성 명령하는 명령어. "Fruit~ 객체를 생성하라! "

-> 메모리 공간에 객체 생성. 인스턴스화 (instantiation) , 생성된 객체-인스턴스(intstance)

(2) 클래스와 객체의 차이점 ( 메모리 관점 )

 -클래스에 존재하는 변수와 메소드는 메모리 공간에 할당된 형태로 존재 x, 접근도 호출도 불가능.(틀로서만 역할)

 -객체는 메모리 공간 할당, 접근과 호출 가능.

 

2) 대입 연산자의 왼편 FruitSeller seller = ... ; / FruitBuyer buyer = ...;

: int num; 과 같은 선언문과 같은 구조. 자료형(FruitSeller or FruitBuyer)가 왼편, 변수의 이름(seller or buyer) 오른편

- 클래스를 정의하는 것은 자바에서 제공하는 기본 자료형 이외에 프로그래머가 새로운 이름의 자료형을 정의하는 것

 

3) 객체 생성 문장 총 정리 분석

(1) FruitSeller seller = new FruitSeller();  : FruitSeller 객체를 생성하고 이를 seller라는 이름의 변수로 참초

(2) FruitBuyer buyer = new FruitBuyer():   :FruitBuyer 객체를 생성하고 이를 buyer라는 이름의 변수로 참조

 

-> 이 두 문장이 실행된 이후로는 각각의 개체에 seller, buyer를 통해서 접근 가능

-> seller & buyer : 참조변수

 

 

 

7. 객체 생성과 참조의 관계

: 키워드 new에 의한 객체 생성시 생성된 객체는 메모리에 저장되고, 저장된 메모리의 주소 값이 반환, 선언된 참조변수에 저장.

 

- 주소값이 저장되었기 때문에 다음의 문장 구성 가능

FruitSeller seller1=new FruitSeller();

FruitSeller seller2=seller1;

 

-> 두 개의 참조변수가 하나의 객체를 참조.

 

** new에 의해 반환되는 주소 값 : 자바에서는 new에 의해 반환되는 주소 값( 참조변수가 저장하고 있는 값 ) 을 '참조' , reference 라고 한다.

 

 

 

===============================객체로의 실체화 끝 =====================================*

8. 생성된 객체의 접근방법

" 연산자를 이용해서 객체의 변수 또는 메소드에 접근한다 " *접근이 가능하려면 접근권한이 있어야 한다. 다음 챕터에서 다룸

1) 참조변수 seller의 예

- seller가 참조하는 객체의 변수 numOfApple에 값 저장하기

seller.numOrApple=20;     //seller가 참조하는 객체의 변수 numOfApple에 20저장

- seller가 참초하는 객체의 메소드 호출

seller.saleApple(10);     //seller가 참조하는 객체의 메소드 saleApple 호출

 

 

 

9. 참조변수와 메소드의 관계

 

public void myMethod()

{

FruitSeller seller1 = new FruitSeller();

instMethod(seller1); //seller1 이 메소드의 매개변수로 전달됨!

}

public void instMethod(FruitSeller seller2) //매개변수 형이 FruitSeller이다.

{

...

}

 

instMethod라는 이름의 메소드 호출, 참조변수 seller1에 저장된 값 전달, instMethod는 seller2라는 이름으로 받음.

 

 

메소드를 호출하면서 참조변수를 전달하는 상황에서 생각할 수 있는 값의 전달 진행의 경우 

1) 참조변수가 메소드의 인자로 전달되면 동일한 형태의 객체가 생성되어(복사) 매개변수가 이를 별도로 참조.  -x

2) seller2에 seller1이 젖아하고 있는 객체의 참조 값(주소 값)이 전달되는 상황. - seller1과 seller2가 하나의 객체를 동시에 참조. -o

 

 

 

 

- 3~13 : Number라는 이름의 클래스 정의, (클래스 안에 존재하는 메소드와 변수의 위치 상관 x)

- 19 : 객체 생성. 참조변수는 nInst

- 20 : nInst가 참고하는 객체의 getNumber 메소드 호출. -> 객체 내에 존재하는 변수 num값 반환, 0

- 22 : 같은 클래스 내의 25행에 정의되어 있는 메소드를 호출하면서 인자로 nInst가 전달, 호출된 메소드 내에서 매개변수 numb로 이를 받고 있다. 그리고 27행에서는 매개변수 numb를 이용하여 addNum 메소드 호출, -> numb가 참조하는 객체에 저장된 변수 num 값이 12증가

- 23행 : 다시 nInst가 참조하는 객체의 getNumber 메소드 호출

 

: numb가 참조하고 있는 객체 내의 변수 num를 변경한 뒤 nInst가 참조하고 있는 객체의 변수num을 출력했더니 numb를 이용하여 변화하기 전과 다른 결과가 나왔다. 즉 참조변수 numb와 nInst는 같은 메소드를 참조하고 있음 -> 메소드로의 참조변수 전달은 객체의 주소값만 전달됨.

 

* 생성되는 class 파일의 수 : 확장자가 .class인 클래스 파일은 정의되는 클래스 수 만큼 생성

 

 

 

10. 참조변수의 null 초기화

: 참조변수 선언 시 특정 개체로 초기화가 이뤄지지 않는다면 null로 초기화 가능

 

MyInst my=null;     //MyInst라는 클래스의 참조변수 my 선언

 

참조변수 my가 객체를 참조하고 있는지 확인하기 위해 다음과 같은 if문도 구성 가능

 

if(my==null) System.out.println("참조변수 my는 현재 참조하고 있는 객체가 없습니다.")

 

+) null로 초기화된 참조변수를 System.out.println메소드로 출력하면 문자열 null이 출력된다.

 

 

 

11. 사과장수 시뮬레이션

-FruitBuyer의 saleApple 메소드 : 구매를 하는데 있어서 필요하지만 클래스 안에 존재하지 않는것 -구매대상(과일장수), 구매금액(2000)

-numOfApple+=seller.saleApple(money); : seller가 참조하는 saleApple가 호출, 반환되는 값의 크기만큼 numOfApple 증가

-buyer.saleApple(seller,2000); : seller가 참조하는 객체는 사과를 판매하고 수익이 생긴다. buyer가 참조하는 객체는 돈을 지불하고 사과를 얻는다. 그 아래에 결과 출력.

 

 

 

12. 객체간의 대화방법(Message Passing방법)

 

위 시뮬레이션의 numOfApple+=seller.saleApple(money); 는 현실세계에서 " seller아저씨, 사과 2000원 어치 주세요"

'나' 라는 객체가 '과일장수'라는 객체로 부터 '과일'객체를 구매하는 행위  )

 

하나의 객체가 다른 하나의 객체에게 메세지를 전달하는 방법은 메소드 호출을 기반으로 함.

->객체지향에서 메세지 전달(Message Passing)이라고 함

 

 

 

13. 객체와 인스턴스

자바에서 객체와 인스턴스는 동일한 의미로 사용. 하지만 표현에 따라 어울리는 상황이 있음.

1) 인스턴스 : 클래스라는 틀을 기바능로 실제화 되었음을 강조할때

" 클래스 FruitSeller의 인스턴스 두 개 생성한다."

2) 객체 : 현실세계의 사물이나 대상을 프로그램상에서 표현되었음을 강조할 때

"과일장수 하시는 옆집 철수 아버님을 의미하는 객체를 생성한다."

 

+) 클래스 안에서 정의되어서, 인스턴스가 생성되어야만 접근이 가능한 변수와 메소드를 가리켜 각각 '인스턴스 변수', '인스턴스 메소드'라고 한다

 

 

* 인스턴스 변수와 인스턴스 메소드 : 메소드라는 이름이 붙은 이유는 메소드가 인스턴스의 행위 및 행동을 표현하는 방법(method)으로 사용되기 때문. 자바에서는 인스턴스 변수를 가리켜 인스턴스 필드(instance field)라고 부르기도 한다.

 

 

 

 

출처 : 난 정말 JAVA를 공부한 적이 없다구요(윤성우 저)

<1> 메소드에 대한 이해와 메소드의 정의

1.  main 메소드에 대해서 우리가 아는것 과 모르는 것


public static void main(String[] args)

{

int num1=5, num2=7;

System.out.println("5+7="+(num1+num2));

}


1) 아는 것 

-main는 메소드이다

-메소드는 클래스 내부에 존재한다

-메소드의 중괄호 내에 존재하는 문장들이 위에서 아래로 순차적으로 실행된다.


2) 모르는 것

-public, static (-> 이번 챕터에서 다루지 않는다) void 가 붙어있는 이유 

-이름이 항상 main인 이유

-메소드 옆에 있는 소괄호와 소괄호 안의 String[] args



2. 다른 이름의 메소드 만들기

* 만들어온 메소드의 이름이 항상 main 이었던 이유 : " 자바 프로그램의 시작은 main이라는 이름의 메소드를 실행하는 데서부터 시작한다."

-> 프로그램의 시작이 목적이 아니라면 얼마든지 다른 이름의 메소드를 만들 수 있다. 

1) main이 아닌 메소드정의 예시

-"hiEveryone 이라는 이름의 메소드 정의 "

-메소드 정의 : 메소드를 만드는것

-메소드 오른쪽 소괄호 : 변수선언.


2) main이 아닌 메소드실행



- 8, 9행 : 메소드 호출문 ( 메소드를 실행하는 문장) 메소드의 이름(전달한데이터); 형태. 호출된 메소드가 다 실행 되고 나서 다음줄으로 넘어간다.

- 12~16행 : 정의한 "hiEveryone" 메소드, 6,7행에서 전달한 데이터가 메소드 이름 옆에 선언된 변수 age에 전달되어 저장, 이렇게 초기화된 변수는       hiEveryone 메소드 안에서 접근 가능

-15행 : 12행에서 선언된 변수의 저장된 값 출력하는 문장 



메소드의 호출과 값의 전달 과정 : 

hiEveryone(12) 를 통해 public static void hiEveryone(int age)의 age에 12저장(hiEveryone실행) -> 저장된 값이 사용되는 문장에서 사용됨. (hiEveryone끝)다시 hiEveryone(12)로 돌아가고 다음 문장으로 넘어감. 

 

*메소드 실행에서 중요한 규칙들 

-메소드 호출문을 접하면 해당 메소드의 실행이 완료된 다음에야 비로소 그 다음 실행

-메소드는 한번 정의됨녀 여러번 실행 가능

-메소드는 메소드이름(값); 으로 호출되고 소괄호에 있는 값이 메소드 정의때 만든 변수에 저장되고 메소드 내에서 사용

-메소드가 정의되는 위치는 프로그램 실행 결과에 영향 x. (hEvery~함수가 main앞에 오든 뒤에 오든 관계 x)


3) 매개변수(parameter) : 메소드의 정의에서 매소드 이름 오른편에 등장하는 변수 

* 메소드 호출시 전달되는 값의 자료형과 매개변수의 자료형은 항상 같아야 한다

- 매개변수가 두개인 메소드와 매개변수가 존재하지 않는 메소드의 예시 

-8행 : 여러개의 값을 전달할때는 , 를 사용하여 구분한다. 

-9행 : 변수에 저장된 값도 전달이 가능하다

-10행 : 값의 전달 없이 메소드 호출

-13행 : int 변수와 double 변수가 순서대로 정의, 따라서 호출할때도 같은 순서로 값을 전달해야 한다

-20행 : 매개변수가 빈 상태로 정의. 따라서 호출할때는 값의 전달이 없어야 한다.



문제1.

Q1 두개의 정수를 전달받아서 두 수의 사칙연산 결과를 출력하는 메소드와 이 메소드를 호출하는 main메소드 정의. 단 나눗셈은 몫과 나머지 각각 출력 

* 여러개의 매개변수를 정의할때 int a,b x int a , int b o 

Q2.  두개의 정수를 전달받아서, 두 수의 차의 절대값을 계산하여 출력하는 메소드와 이 메소드를 호출하는 main 메소드를 정의해보자. 단 메소드 호출 시 전달되는 값의 순서에 상관없이 절대값이 계산되어서 출력되어야 한다.

- 내가 한것

-책에 나온 것





2. 값을 반환하는 메소드

1) 메소드 이름의 왼쪽에는 반환하는 값의 정보를 삽입하게 되어있다.  

-main앞의 void - "이 메소드는 값을 반환(메소드를 호출한 영역으로 값을 전달하지) 않는다." (5행의 main)

     -12행, 18행 : adder메소드는 int형 데이터 반환, square메소드는 double형 데이터 반환. 


2) 값의 반환 

메소드 adder

-int : 반환하는 데이터의 자료형

-return : return의 오른쪽에 등장하는 대상 반환(상수, 연산문(연산의 결과 반환), 변수) , 실행시 메소드 종료, 메소드를 호출한 영역으로 값 반환. 

-> int result = adder(4,5) -> int result = 9;  

* return addResult : add Result에 저장되어 있는 값 반환  "값의 반환은 메소드의 호출문장이 반환된 값으로 대체됨"

- 메소드는 호직 하나의 값만을 반환할 수 있음



3. 키워드 return이 지니는 두가지 의미

1) 값의 반환

2) 메소드의 종료 

-> 메소드 중간에 return문이 실행되면 메소드의 나머지 부분은 실행이 이뤄지지 않고 메소드 종료. 




* void 표시가 된 메소드 내에서 반환 목적이 아닌 오로지 메소드의 종료를 목적으로 return문 사용 가능 

-> 반환 대상 없이 그냥 키워드 return으로만 구성(반환 대상 있으면 안됨)



문제2

Q1. 원의 반지를 정보를 전달하면 원의 넓이를 계산해서 반환하는 메소드와 원의 둘레를 걔산해서 반환하는 메소드를 각각 정의하고, 이를 호출하는 메소드 정의

-내가 한 것



- 책에 나온 것





Q2. 전달된 값이 소수(prime number)인지 아닌지를 판단하여 소수인 경우 true, 소수가 아닌 경우 false를 반환하는 메소드 정의 이를 이용하여 1이상 100이하의 소수를 전부 출력할 수 있도록 main함수 정의

- 내가 한 것



- 책에 나온 것 

*1은 소수가 아님. - 결과는 내가 한 결과에서 1만 빠진다.





<2> 변수의 스코프 : 변수의  접근, 변수가 존재할 수 있는 영역

1. 가시성 (visiblity) 

* 중괄호로 영역이 형성되면 감싸이는 영역은 변수에 관한 별도의 스코프 형성


1) 동일한 이름의 변수가 여러개 선언되는 예시

: 선언된 변수가 속하는 중괄호의 영역(스코프)이 다르기 때문에 같은 이름의 변수를 여러개 선언가능. 

-10행의 num : 8행의 if에 속하는 중괄호

-16행의 num : 14행의 else에 속하는 중괄호

-25행의 num : 23행의 simple에 속하는 중괄호

*변수는 자신이 족한 중괄호 내에서만 접근 가능(선언된 이후부터) 

*for과 메소드의 매개변수는 중괄호 내에서 선언되지는 않지만 이어서 등장하는 중괄호 내에서만 접근 가능. 

( 그 영역 내에서는 같은 이름의 변수를 선언할 수 없다.)



2) 해당 영역을 벗어나면 사라진다

- 지역변수 : 중괄호 , for문 안에서 선언되는 변수와 매개변수

" 지역변수는 선언된 지역을 벗어나 버리면 메모리 공간에서 자동으로 소멸 "




<3> 메소드의 재귀호출

: 자바는 메소드의 재귀호출 지원, 자료구조와 알고리즘에서 유용하게 사용된다.


1. 수학적 측면에서 재귀적인(순환적인) 사고 - 팩토리얼의 예

1) 팩토리얼(factorial) n! : n까지의 숫자를 다 곱하는 것   


5! = 5 x 4 x 3 x 2 x 1

4! = 4 x 3 x 2 x 1

3! = 3 x 2 x 1

2! = 2 x 1

1! = 1


다르게 표현하면


5! = 5 x 4!

4! = 4 x 3!

3! = 3 x 2!

2! = 2 x 1!

1! = 1


: 재귀 - 팩토리얼의 계산식에서 다시 팩토리얼이 등장한것 . 



팩토리얼을 수학의 함수식으로 정의하면   

: f(n)={ n x f(n-1) (n>=2)  or  1 (n=1) }  (편의를 위해 0이상이 아닌 1이상으로 표현)


이와 같은 맥락으로 자바는 메소드 f의 부분에서 메소드 f의 호출문이 삽입되는 것 허용



2. 재귀적 메소드의 정의



1) 수학식과의 관계 : 

f(n) = { 1 (n=1) }  :  if (n ==1) return 1;

f(n) = { n x f(n-1) (n>=2) } : else return n*factorial(n-1);


2) 7행의 메소드 호출부터 factorial 메소드가 실제로 동작하는 방식

3) 아직 실행이 완료되지 않은 메소드를 다시 호출하는 방법 : 메모리에 저장된 메소드를 구성하는 명령문이 cpu로 이동해서 실행

 : 메소드의 앞 부분을 구성하는 명령문만 반복해서 cpu로 이동시킬 수 있다

 

 

3. 잘못된 재귀 메소드 : 종료조건의 부재

 

 

- 위 코드의 문제

(1) --cnt : 재귀호출이 일어난 다음에 cnt가 줄어들으므로 같은 매개변수를 가진 showHi가 계속 일어난다.

(2) if(cnt==1) return; : 조건검사 부분. 매개호출 아래에 들어가므로 조건검사부분이 실행되지 않는다

 

-올바르게 고친 코드

 

 

 

* 재귀 메소드 정의의 주의사항

(1) 재귀의 연결고리를 끊기 위한 조건검사의 위치가 적절해야 한다

(2) 재귀의 연결고리를 끊기 위한 조건검사가 true가 되도록 적절한 연산이 이뤄져야 한다

 

 

4. 과도한 메모리 사용

: 성능의 저하로 이어질 수 있다

1) 그럼에도 불구하고 재귀 메소드가 가진 장점

- 복잡한 문제를 간결하게 해결하는 열쇠

- 비교적 짧은 코드가 요구된다.

 

 

문제 3

Q1. 정수 N을 전달받아서 2의 N승을 반환하는 베소드를 재귀의 형태로 정의하고 이의 테스트를 위한 main 메소드도 함께 정의하자

 

 

 

* 책에서는 if (N==0) retrun 1; 로 하였다.

 

Q2. 10진수 정수를 전달받아서, 전달받은 정수에 해당하는 2진수를 출력하는 메소드를 재귀의 형태로 정의하고, 이의 테스트를 위한 main 메소드도 같이 정의하자. 참고로 아직은 다양한 출력방법을 소개하지 않았으니 여러 줄에 걸쳐서 출력이 이뤄지도록 메소드를 정의하자

 

: 나의 풀이

-binary(n) = { print(n%2) binary(n/2)  ,  1 (n이 1일 때) }  *%과 /는 java에서의 의미를 갖고있다

-2로 나눠가며 나머지 출력

-2진수를 한 줄에 나타냈을 때 맨 왼쪽에 와야하는 수를 알아보기 위해 a를 같이 출력했다.

-과정을 보기 위해 맨 왼쪽에 와야하는 수가 아닌 다른 수들의 뒤에 b와 dec을 같이 출력했다

 

=> 위에서 부터 왼쪽이 아니라 오른쪽 수가 출력. 위 아래로 순서가 바껴야 하는 경우. 나머지 출력을 재귀호출 뒤에 넣는게 좋다고 생각

 

*a와 b, dec를 지우면 코드 완성.

 

: 책에 나온 코드

 

 

차이점

- if 괄호 안 (조건검사) return의 경우/return이 아닌 경우

- 조건검사 : dec=1 , dec=0

- 메소드의 자료형 : void / int

- 변수의 사용 : 변수 x / 나머지변수 bin

-dec or decimal 의 변화 : 메소드호출 안에서 / 메소드호출 밖에서

 

 

 

'언어 > JAVA' 카테고리의 다른 글

Chapter 7. 클래스와 인스턴스 (2)  (0) 2017.05.26
Chapter7. 클래스와 인스턴스  (0) 2017.05.18
Eclipse 설치 및 실행  (0) 2017.05.11
Chapter5. 실행흐름 컨트롤(2)  (0) 2017.05.06
Chapter5. 실행흐름 컨트롤(1)  (0) 2017.05.01

<설치>

 

1.https://www.eclipse.org 홈페이지에서 Download 버튼 클릭

 



2. 64bit인 것을 확인하고 DOWNLOAD 64 BIT 클릭 



3.  Select Anther Mirror 클릭 -> Daum Kakao Corp




4.  저장 완료




4. eclipse installer -> Eclipse IDE for Java EE Developers




5. Install (중간에 나오는 Oomph 라이센스에 동의




6. 설치 후 실행




7. 오른쪽 상단의 Workbench버튼을 누르면 Welcome화면을 벗어날 수 있다.




<실행

나는 위치지정 화면에서 C:\workplace로 위치를 설정하였다.  

 

1. New - Java Project   or   New-Project-Javaproject




2. 이름설정 -> Finish



 

3. test 왼쪽 삼각형을 눌러 확장한 후 src에서 마우스 오른쪽 버튼을 눌러 New-Package (Packageclass를 기능별로 분류하는 것인데 , 나중에 소스코드가 많아졌을때 편리하다고 한다.)

 



4. Package 이름 설정. Finish

 



5. Packagetest에서 마우스 오른쪽 버튼 New-class 




6. Name를 설정하고 public static void main(String[] args 를 체크한다. Finish




7. HelloJava를 출력하는 System.out.println("HelloJava"); 작성. HelloJava.java 에서 마우스 오른쪽 버튼 - Run As - Java Application




8. 실행완료



 

 

 

 

출처 : http://pentode.tistory.com/65 

'언어 > JAVA' 카테고리의 다른 글

Chapter7. 클래스와 인스턴스  (0) 2017.05.18
Chapter 6. 메소드와 변수의 스코프  (0) 2017.05.14
Chapter5. 실행흐름 컨트롤(2)  (0) 2017.05.06
Chapter5. 실행흐름 컨트롤(1)  (0) 2017.05.01
chapter4. 연산자(Operator) (2)  (0) 2017.04.12

<3> for, while 그리고 do~while

* 반복문의 조건 : 변수선언, 조건문, 반복문을 깰 문장

 

1. while 반복문

1) 기본구조

while(조건문)

{

실행할 문장;

반복을 깰 문장;

}

** 실행할 문장과 반복을 깰 문장의 순서는 무관하다

 

 

조건확인 -> 문장실행(+변수바뀜) -> 조건확인.->문장실행 ....->조건성립x

 

 

2) 예제

 

:

num=0 (변수선언) -> while (num<5 -> 문장실행, num=1 -> num<5 ->문장실행, num=2 -> num<5 -> 문장실행, num=3 -> num<5 -> 문장실행, num=4 -> num<5 -> 문장실행, num=5 -> num <5 성립 x )  

 

 

3) 특징

-반복조건을 먼저 검사후에 반복영역의 실행여부 결정

-반복조건을 먼저 검사하기 때문에 반복영역이 한차례도 실행되지 않을 수 있다.

 

 

2. do~while 반복문

1) 기본구조

do

{

반복영역

} while(조건문);

 

반복영역 실행 -> 조건확인 -> 반복영역실행 ... ->조건성립 x -> 끝

* 반복영역을 시작할때 실행한다는 점이 while 문과의 유일한 차이점이다.

 

2) 예제

 

변수선언 (num=0) -> do while문 ( 반복영역 실행, num=1 -> num<5 -> 반복영역실행, num=2 -> num<5 -> 반복영역실행, num=3 -> num<5 -> 반복영역실행, num=4 -> num<5 -> 반복영역실행, num=5 -> 조건성립x )

 

3) 특징

-반복영역을 먼저 실행 한 다음에 반복조건을 검사한다

-반복영역을 먼저 실행하기 때문에 반복조건을 만족하지 않아도 한 차례는 실행된다.

-> 최소한 한차례의 실행이 필요한 경우 do while문 실행  

 

 

 

 

문제4

Q1. 1~99까지의 합을 구하는 프로그램 while문 이용하여 작성 

 

 

 

Q2. 1~100까지 출력하고 난 다음에, 다시 거꾸로 100에서부터 1까지 출력하는 프로그램을 작성해보자. while문과 do while문을 각각 한번씩 사용해야 한다.

 

- 내가 한 코딩

-책의 코딩

 

Q3. 1000이하의 자연수 중에서 2의 배수이면서 7의 배수인 숫자를 출력하고, 그 출력된 숫자들의 합을 구하는 프로그램을 while문을 이용하여 작성해보자.

:

 

 

 

 

 

 

3. for 반복문

 

1) while, do while문에서 따로 떨어져있던 변수선언, 조건문, 반복의 조건을 무너뜨리기 위한 연산을 한줄에 나타낸것. - 정해진 횟수의 반복을 위해 존재.

-while 문

int num=0;

while(num<5)   

{

System.out.println("...");

num++;

}

 

-for 문

for(int num=0 ; num<5 ; num++)

{

System.out.println("...");

 

2) 예제

 

3) 실행순서.

-첫번째 루프 : int i=0; -> i<3 -> 실행문장 -> i++; (변수선언 -> 조건확인 -> 실행문장 -> 변수변화) i=1

-두번째 루프 : i<3 -> 실행문장 -> i++; (조건확인 -> 실행문장 -> 변수변화) i=2

-세번째 루프 : i<3 -> 실행문장 -> i++; (조건확인 -> 실행문장 -> 변수변화) i=3

-네번째 루프 : i<3 (=거짓) 탈출!

 

*for문에서 선언되는 변수는 for문 내에서만 유효한 변수

*조건문을 제외한 영역에서 콤마를 사용해 여러 연산들을 사용할 수 있다

ex) for(int i=0, j=7; i<j ; i++,j--)

System.out.println("I love Java"+i+j);

-> 출력결과:

I love Java 07

I love Java 16

I love Java 25

I love Java 34

 

 

 

문제 5

Q1. 1부터 10까지 곱해서 그 결과를 출력하는 프로그램을 for문을 이용하여 작성하자

 

Q2. 구구단 5단을 출력하는 프로그램을 for을 이용하여 작성하자.

 

 

 

 

 

 

<4> continue & break : 반복문 내에 삽입되어 실행 흐름을 조절하는데 사용된다.

1. break문 : 가장 근접한 거리에서 자신을 감싸는 반복문을 빠져나간다.

* if 문과 함께 구성되어 특정조건이 만족될 때 반복문을 빠져나간다.

1) 예제

- 5와 7의 최소공배수를 찾는 프로그램

-5와 7의 최소공배수를 발견하면 break; 때문에 바로 while문을 빠져나간다.

-5와 7의 최소공배수가 존재하면 search는 true, if문을 실행하고 존재하지 않는다면 search는 false, else 아래의 문장을 실행한다.

 

2. continue문 : 반복문의 나머지 부분을 생략하고 프로그램의 흐름을 "조건검사 부분으로 이동" - 계속진행

*if문과 함께 유용하게 사용할 수 있다.

1) 예제 : 100이하의 자연수 중에서 5의 배수이자 7의 배수인 수를 출력하고 갯수를 세어보는 프로그램

-coutinue를 만나면 그 아래의 문장을 실행하지 않고 바로 조건검사를 진행한다

-num++<100 : 1. num<100 의 값 return 2. num++  ----조건검사와 반복문을 깨트릴 연산을 한꺼번에 넣었다.

-count 변수를 넣어 갯수를 센다

 

3. 무한루프와 break

1) 무한루프 : 조건문에 true가 명시되어 해당 반복문을 빠져나가지 못하도록 구성된 반복문

2) while 무한루프

while(true)

{

...

}

3) do while 무한루프

do

{

...

} while(true);

 

4) for 무한루프 (조건을 명시하는 부분을 비우는 유형이 더 일반적이다)

 for(;true;)

{

..

}

 

 

or

 

 

for( ; ; )

{   

...

}

 

// 조건을 명시하는 부분을 비우는 유형이 더 일반적이다

 

 

5) break문과 결합되어 사용되는 예제 : 6과 14의 최소공배수를 찾는 프로그램

: 무한루프를 이용한 이유 : 6의 배수이면서 14의 배수가 되는 수를 예측하지 않아도 되기때문. 잘못 예측한다면

 

while(num<30)

{

if(num%6==0 && num%14==0)

break;

num++;

}

 

같이 반복문을 잘못 구성할 수도 있다.

 

 

문제 6 [continue문과 break문의 활용]

Q1. ContinueBasic.java의 내부에 존재하는 while문을 for문으로 변경해서 예재를 재구현

-ContinueBasic.java

-(1) 책에서와 같은 코드

 

-(2)

 

 

 

Q2. 자연수 1부터 시작해서 모든 홀수와 3의 배수인 짝수를 더해 나간다. 그리고 그 합이 언제 (몇을 더했을 때) 1000을 넘어서는지, 그리고 1000을 넘어선 값은 얼마가 되는지 계산하여 출력하는 프로그램. 단 프로그램 내에서 반복문을 필요로 한다면 반드시 while문 무한루프로 구성.

 

-

 

 

- 중간중간 확인

 



<5> 반복문의 중첩

: 반복문은 총 9가지의 형태로 (for, while, do while 3가지 x 3가지) 중첩될 수 있다.

1. 가장 많은 for문의 중첩

1) 예제

-첫번째 for문 i 바꿔가며 3번 반복

-두번째 for문 j 바꿔가며 3번 반복


2) 구구단 만들기 예제

: 2~9단이 2~9까지 곱해지며 구구단이 이루어 진다. 단수를 바깥 for문으로, 곱해지는 수를 안의 for문으로 구성한다


* 9단은 구현되었으나 사진에는 나오지 않았다. 


2. while문의 중첩 

1) while문의 구구단

: 변수선언, 반복을 깨트릴 연산 등이 밖에 따로 있다. j=1; 이 첫번째 while문 안에 있는 것이 주목할 만 점이다.


3. 레이블을 설정하는 break문

1) 보통의 break문은 가장 가까히서 감싸는 하나의 반복문 밖에 빠져나가지 못한다.

: i와 j가 모두 짝수이면 break;을 실행하는 프로그램. 위 결과에서 break이 j에 대하여 반복하는 안쪽 코드만 빠져나간 것을 알 수 있다.


2) 빠져나갈 위치를 명시하는 break문( 레이블을 설정하는 break문)

outerloop:

for(int ~~~) 는 outerloop : for(~~~) 을 보기좋게 나타낸 것.


break outerloop; 는 outerloop라고 표시된 반복믄을 빠져나가겠다는 선언이다. 


--> 물론 다른 이름으로 표시도 가능. (원하는대로 가능하다)





문제 7

Q1. 구구단의 짝수 단(2,4,6,8단)만 출력하는 프로그램을 작성하되, 2단은 2x2까지, 4단은 4x4까지, 6단은 6x6까지, 8단은 8x8까지만 출력하도록 구현


 


- 책에서 나온 코드

Q2. 다음 식을 만족하는 모든 A와 B의 조합을 구하는 프로그램

AB

         +BA

-------------

99



'언어 > JAVA' 카테고리의 다른 글

Chapter 6. 메소드와 변수의 스코프  (0) 2017.05.14
Eclipse 설치 및 실행  (0) 2017.05.11
Chapter5. 실행흐름 컨트롤(1)  (0) 2017.05.01
chapter4. 연산자(Operator) (2)  (0) 2017.04.12
chpter4. 연산자(Operator)  (0) 2017.04.07

<1>  if 그리고 else

:특정 조건이 만족될 때에만 실행하고픈 문장이 있을때(if), 조건에 따라 실행하고픈 문장을 달리 하고싶을때 (else)

 

1. if 문과 if~else 문

 

1) if 뒤의 소괄호() : 안에는 true와 false 반환하는 연산식

2) 소괄호 안이 true이면 아래의 문장 실행, false면 실행 x else 가 있을 시 else 아래의 문장 실행

 

: 첫번째 if 문의 소괄호 안에 false가 들어갈 경우

 

 

 

: 두번째 if 문의 소괄호 안에 true가 들어갈 경우

 

3) if~ else 문의 실직적 활용의 예

- 소괄호 안에 연산을 넣어 true나 false를 반환하게 할 수 있다

- 실행시킬 문장이 하나라면 중괄호 생략 가능

 

 

* if ~ else 는 하나의 문장

: 자바에서 라인의 수는 결코 중요하지 않다. 한문장 - 여러라인, 여러문장 - 한라인 구성 가능. 따라서 if~ else문을 한줄에 표현해야 할 필요는 없지만 그 중간에 다른 문장이 오면 에러가 발생한다

 

2. if~else 문의 중첩과 중괄호의 생략 (else if )

: if 문 / if~else 문 내에 또다시 if문이나 if~else 문 삽입 가능.

 

1) 충접

 

: num<0 이라면 "num은 0미만"

0 <= num < 100이라면 "0이상 100미만"

100 <=num 이라면 "100이상"

 

2) 중괄호의 생략 : else if

 

-

 

- else if 문 -

 

 

 

- 중간에 else if 는 얼마든지 삽입할 수 있다. if~ else if~ else 문은 최소한 하나의 문장은 실행되는 구조. 순서대로 읽히며 조건에 해당될 때 해당 문장을 실행하고 if ~ 문을 나가므로 순서가 중요하다.

 

 

Q1 아래의 코드를 if 문 하나만 사용하는 방식으로 변경하라.

:

 

 

Q2   중첩문 예제를

num < 0 일때 "0 미만" , 0<=num<100 일때 "0이상 100미만" , 100<=num<200 일때 "100이상 200미만" , 200<=num<300 일때 "200이상 300미만" , 300<=num 일때 "300d 이상 " 을 출력하도록 예제를 변경하라

 

(중첩문 예제)

:

 

 

:

 

 

 

 

3. if~else와 유사한 조건 연산자

:피연산자가 세개인 유일한 연산자. 간단한 if~elsel문 대체하는 용도로 사용

소괄호 생략 가능, 하지만 구독성을 위해 소괄호 사용

 

 

기본구조 : true of false ? 숫자1 : 숫자2

 

?기호의 왼편에 true가 등장하면 : 기호의 왼편에 있는 숫자 반환

?기호의 왼편에 false가 등장하면 : 오른편에 있는 숫자 반환

 

 

 

Q3 위의 조건연산식 코드를 조건연산자를 사용하지 않고 if~else를 사용하는 형태로 변경해보자.

 

:

 

 

 

 

 

 

<2> switch와 break

1. switch문의 기본 구성 : switch, case, default

 

switch(n)

{

case 1:

...

...

case 2:

...

...

case 3:

...

...

default:

...

}

 

1) label (case, default) : 위치를 표시하기 위해 사용

- case 해당값: : 주어진 변수가 해당값이면 이 위치에서부터 실행

- default : : 변수에 해당하는 레이블이 없으면 이 위치에서부터 실행 ( 생략가능 )

 

 

*n, case에 주어진 값은 정수나 문자만 가능하다. case에 주어진값 상수만 가능.  

 

예제1 : n이 3일경우

 

예제2 : n이 5일경우

 

: 레이블이 지정하는 위치부터 switch의 마지막까지 실행하고 switch문 밖의 것을 실행한다.

 

 

2. switch문 + break문 : switch문의 일반적인 사용 모델

1) switch문 안에서의 break문 : switch문을 그냥 빠져나간다.

2) 레이블 안에 break을 넣게 되면 원래는 해당 레이블 부터 switch문의 끝까지 실행하던 형태에서 해당 레이블만 실행하는 구조가 된다.

 

switch(n)

{

case1:  //영역1

...

break;

case2: //영역2

...

break;

case3: //영역3

...

break;

default: //영역4 (굳이 break을 붙여줄 필요 없다)

...

}  

 

예제 : Switchbasic1 에서 case레이블 마다 break를 추가

n=2

 

n=3

: 해당하는 레이블만 실행된다.

 

 

 

3) 한줄에 둘 이상의 레이블도 붙일 수 있다 .

 

 

 

n= 1/2/3 일 경우

 

 

n=4/5일 경우

 

n이 1/2/3/4/5 외의 수일 경우

 

 

 

퀴즈 :

Q1. SwitchBreak.java를 if~else 문을 이용하는 형태로 변경해보자.

 

- SwitchBreak.java

 

 

:

 

* 안되는 경우*

n==3의 if문만 else와 짝이므로 n==3이 아닌 모든 경우에 (특히 1,2) else문이 실행된다.

 

 

Q2. 아래의 예제를 if~else문이 아닌 switch문을 활용하는 형태로 변경해보자.

 -내가 한것 :

 

 

 

 

- 책에 나온 것 :

 

'언어 > JAVA' 카테고리의 다른 글

Eclipse 설치 및 실행  (0) 2017.05.11
Chapter5. 실행흐름 컨트롤(2)  (0) 2017.05.06
chapter4. 연산자(Operator) (2)  (0) 2017.04.12
chpter4. 연산자(Operator)  (0) 2017.04.07
chapter3. 상수와 형변환(Type Casting)  (1) 2017.04.06

<2> 단항연산자

1.  부호 연산자로써의 +와 -

 

예시 1 ( ** n3와 n4를 short 가 아닌 int로 받았다. )

1) 기능

- + : 특별히 하는 일이 없다 (양수임을 강조할 때 사용된다)

- - : 부호를 바꾸는 역할을 한다.

 

2) 특별히 하는 일이 없는 + 연산자

예시1에서 n3, n4를 short 가 아닌 int로 받고 있음을 볼수 있다.

- short로 받을 경우 : 컴파일에러. => 연산이 일어나면서 n2가 int로 바꼈기 때문이다.

 

 : 컴파일에러. => 연산이 일어나면서 n2가 int로 바꼈기 때문이다. 즉 +연산자는 딱히 하는일은 없지만 실제 연산의 과정을 거친다.

 

-강제형변환

 

 

 

2. 증가, 감소 연산자 (++, --) : prefix (++n, --n)

1) 기능

++ : 피연산자에 저장된 값을 1증가

-- : 피연산자에 저장된 값을 1감소

2) prefix : 접두사

=> 피연산자의 값에서 변화시킨 값을 의미하는것이 아니라 피연산자값 자체를 변화시킨다. 선증감 후연산

 

 

 

 

3. 증가, 감소연산자(++,--) : postfix (n++ , n--)

1) postfix : 접미사  

 

: num1 값의 변하긴 하지만 num2, num3에는 변하기 전의 값이 저장된다. 선연산 후증감

( 대입연산이 증감연산(Postfix)보다 우선순위가 높아서가 아니다.) 

=> 연산이 이루어지는 순간 num1의 값 변화, 하지만 문장에서는 변화되기 전의 값으로 인식하여 연산.

 

예시)

 

 

 

 

 

 

 

<3> 비트연산자

1) 비트연산

: 비트단위로 연산 진행, 비트단위로 진행된 연산의 결과를 묶어서 하나의 연산결과를 반환.

- 2진수의 형태로 변환시켜서 같은 자리에 있는 비트끼리 연산을 하고 그 연산의 결과를 합쳐서 정수로 반환한다.

- 정수만 가능하다 (실수x)

 

 

: (형변환 고려 x) 13 비트단위로 00001101 7 비트단위로 00000111

   00001101

& 00000111 = 00000101 = 5

 

 

2) 비트연산자

연산자 

연산자기능 

결합방향 

 &

 비트단위 and 연산  n1&n2;

: 둘다 1일때 1반환 

 ->

 |

 비트단위 or 연산 n1 | n2;

: 하나만 1이어도 1반환

 ->

 ^

 XOR연산 n1 ^ n2;

: 두 피연산자의 값이 다를때 1반환

 ->

 ~

 모든 비트를 반전시킨다 ~n1;

: 1 -> 0 , 0 -> 1

 <-

 

예시)

 

 

 

3) 비트 쉬프트(Shift)연산자 : <<, >>, >>>

- 비트열을 오른쪽 또는 왼쪽으로 이동시키는 연산자

- 이항연산자

- 피연산자가 모두 정수여야 한다

연산자 

연산자의 기능 

결합방향 

 <<

-비트열을 왼쪽으로 이동

-이동에 따른 빈공간은 0으로 채움

-n<<2; 두칸 왼쪽으로 이동시킨 결과 반환

 ->

 >>

 -비트열을 오른쪽으로 이동

-이동에 따른 빈공간은 음수의 경우 1, 양수의 경우 0으로 채움

-n>>2; 두칸 오른쪽으로 이동시킨 결과 반환

-> 

 >>>

-피연산자의 비트열을 오른쪽으로 이동

-이동에 따른 빈 공간은 0으로 채움

-n>>>2; 두칸 오른쪽으로 이동시킨 결과 반환 

-> 

 

예시)

<< : 2^n 만큼씩 늘어난다

>> : (1/2)^n 만큼씩 늘어난다

>>>: 양수에 한정해서 (1/2)^n만큼 늘어난다.

 

* 비트쉬프트연산자는 CPU의 연산능력이 약한 소형 컴퓨터에서 많이 쓰인다.

 

 

 

퀴즈

Q1. 7의 2의 보수를 계산하여 출력하는 프로그램 만들기

 

 

Q2. 

'언어 > JAVA' 카테고리의 다른 글

Chapter5. 실행흐름 컨트롤(2)  (0) 2017.05.06
Chapter5. 실행흐름 컨트롤(1)  (0) 2017.05.01
chpter4. 연산자(Operator)  (0) 2017.04.07
chapter3. 상수와 형변환(Type Casting)  (1) 2017.04.06
chapter2. 변수와 자료형  (0) 2017.04.05

<1> 이항연산자

 

: 피연산자가 두개인 연산자.

1. 연산순서의 결정

1) 우선순위(1차적 요소) : 여러 종류의 연산자가 있을때의 연산순서

2) 결합방향(2차적 요소) : 같은 연산자가 있을때의 결합순서

 

2. 대입연산자(=) 와 산술연산자(+ - * / %)

1)

연산자 

산자의 기능 

결합방향 

 =

 연산자 오른쪽에 있는 값을 왼쪽에 있는 변수에 대입한다

 ( val=20;)

<-

 +

 두 피연산자의 값을 더한다

 (val = 4+3;)

->

 -

 왼쪽의 피연산자 값에서 오른쪽의 피연산자 값을 뺀다

 (vl=4-3;)

->

 *

 두 피연산자의 값을 곱한다

 (val=4*3;)

->

 /

 왼쪽의 피연산자 값을 오른쪽의 피연산자 값으로 나눈다

 (val=7/3;)

->

 %

 왼쪽의 피연산자 값을 오른쪽의 피연산자 값으로 나눴을 때 얻게되는 나머지를  반환한다.

 (val = 7%3;)

->

 

2) 예제 

 

-result선언 : 선언문에도 연산이 올 수 있다.

-System.out.println("곱셈결과 : "+n1*n2); ... 나머지 결과 : 덧셈연산과 곱셈연산 및 나머지, 나눗셈 연산이 같이 오는데 곱셈연산, 나눗셈연산, 나머지연산이 먼저 계산이 된다.

-나눗셈 연산결과가 정수이다 ** 다음 파트에서 다룬다.

 

 

3)'구분자'소괄호의 이용

: 소괄호를 이용하면 우선순위를 기억하지 않고도 원활하게 연산자를 사용할 수 있다. 

위의 예제에서 곱셈, 나눗셈, 나머지 연산을 소괄호를 이용해 표현하면 

System.out.println("곱셈 결과 : " + (n1*n2));

System.out.println("나눗셈 결과 : " +(n1/n2));

System.out.println("나머지 결과 : " +(n1%n2));

 

 

3. 나눗셈 연산자와 나머지 연산자

1)

정수형 나눗셈 : 정수의 몫 + 정수의 나머지 발생 / 두 개의 연산자가 모두 정수이면 발생 , 몫을 반환한다

실수형 나눗셈 : 실수형태의 결과. /두 개의 연산자가 실수이면 발생

 

예제 )

-정수형 나눗셈 : 피연산자가 둘 다 정수이기 때문에 정수형 나눗셈을 실행하였다

-실수형 나눗셈 : 피연산자가 둘 다 실수이기 때문에 실수형 나눗셈을 실행하였다 (f를 안써도 실수형 나눗셈이 발생한다. double형 결과 반환)

-형변환 나눗셈 : (float)7/3  -> 7.0f/3  -(자동형변환)-> 7.0f/3.0f -> 2.3333333

*형변환에 사용되는 소괄호는 '구분자' 가 아니고 '연산자' 이다

 

 

2) 나머지 연산자

: 실수의 나눗셈은 컴파일 오류가 발생하진 않지만 나머지가 존재하지 않는것이 수학적 원칙이기 때문에  나머지 연산은 무의미 하다.

예제 )

** 실수 저장/출력 과정에서 오차

 

 

4. 복합(Compound) 대입 연산자

: 피연산자1 연산 = 피연산자2    (==)   피연산자1 = 피연산자1 연산 피연산자2

: 대입연산자와 다른 연산자를 묶은 형태의 연산자.

 

 복합대입연산자

동일연산 

 a+=b

a=a+b 

 a-=b

a=a-b 

 a*=b 

a=a*b 

 a/=b

a=a/b 

 a%=b

a=a%b 

 

+) &=, ^=, |=, <<=, >>=, >>>= (비트연산자 * )

 

예제)

 

e: (double) 3.1 + (double) 2.1 = (double) 5.2   ,    (double) 5.2 * (int) 2 -> (double)5.2 * (double)2.0 , e=(double) 10.4

n : (int) 5, (int)5 + (double)2.2 -> (double)5.0 + (double) 2.2 -> (double) 11.0 -> (int) 11

* 곱센연산 이후 대입의 과정에서 자료형의 불일치로 인한 문제가 발생하지만 이는 어디까지나 *=연산의 일부이기 때문에 컴파일 에러를 발생시키지 않는다.

 

 

 

 

5. 관계연산자 (>,<,>=,<=,==,!=) (비교연산자)

: 크기 및 동등관계를 따지는 연산자

 

 연산자

연산자의 기능 

결합방향 

 <

n1<n2

n1이 n2보다 작은가? 

 -> 

 >

n1>n2

n1이 n2보다 큰가?

 ->

 <=

 n1<=n2

n1이 n2보다 작거나 같은가?

 ->

 >=

 n1>=n2

n1이 n2보다 크거나 같은가?

 ->

 ==

n1==n2 

n1과 n2가 같은가?

 ->

 !=

n1!=n2 

n1과 n2가 다른가?

 ->

 

 

- 결과에 따라서 false of true를 반환한다. (1byte)

- boolean result = (a==B); //소괄호 생략 가능

 

예제 ) 관계연산자의 활용

 

* if~else문 : true면 if문, false면 else문

 

 

 

6. 논리 연산자 (&& , ||, !)

 연산자

연산자의 기능 

결합방향 

 &&

A && B

논리and, 둘다 참이어야 참이다 

-> 

 ||

A || B

논리 or 둘중에 하나라도 참이면 참

 ->

 ! (->단항연산자)

 !A

A가 true면 false, false면 true

 <-

 

 

예제 ) 기능

 

- && / || 연산자 보다 ==, <=, >=이 우선순위가 더 높기 때문에 ==, <=, >= 연산 먼저 실행되고 그 결과로 &&, ||연산을 실행한다.

 

 

 

7. *우선순위가 없더라도 !

num1==10 && num2==20 의 실행이 우선순위에 의해서만 ==연산이 먼저 진행되는 것 x

가정 ) &&연산이 == 연산보다 우선순위가 높다면

" &&연산의 피연산자로 false나 true대신 ==연산이 있다 -> ==연산의 결과를 받아야한다! " 

따라서 결국엔 ==연산을 먼저 하게 된다.

 

이는 &&연산자와 ==연산자가 대등한 위치가 아닌 &&피연산자로 ==가 놓여있는 위치이기 때문

 

 

 

8. 논리연산자와 Short-Circuit Evaluation (Lazy Evaluation) (SCE)

 

: num2의 값이 하나도 증가하지 않았다.

-> SCE의 특성.

&&연산의 경우 앞의 연산이 false일때 결론이 false로 나오므로 뒤의 연산은 볼것도 없다는 판단이 나서 연산을 하지 않는다.

||연산의 경우는 유사하게 앞의 연산이 true일 경우 결론이 무조건 true로 나오므로 뒤의 연산은 볼것도 없다는 판단이 나서 연산을 하지 않는다

--> SCE의 부작용이 될 수 있으므로 조심해야 한다.

 

 

 

 

 

 

9. 퀴즈

Q1. int형 변수 num1, num2, num3가 각각 10,20,30으로 초기화되어 있는 상황에서 num1=num2=num3; 를 하면 각각의 변수에는 얼마 저장?

답 :

 

num1 : 30, num2 :30 , num3=30

이유 : 결합방향이 <- 이므로 오른쪽에 있는 =연산이 먼저 실행된다 즉, num1 = (num2 = num3) 의 순서로 진행.  

(num2에 num3에 저장된 값이 저장되고, num2에 저장된 값이 num1에 저장)

 

Q2. SCE 예제의 실행결과를 보면 num2가 증가하지 않음을 확인할수 있는데, 이는 SCE에 의해서 두번이나 등장하는 num2+=10이 전혀 실행되지 않기 때문이다. num2+=10이 실행되도록 코드를 수정.

내 풀이 :  

 

-> num1, num2의 초기화 수를 바꾸거나 연산을 바꾸면 원하지 않는 결과가 나올 수 있다.

교재의 풀이 : 문장이 많아졌지만 간결해졌다.

 

'언어 > JAVA' 카테고리의 다른 글

Chapter5. 실행흐름 컨트롤(1)  (0) 2017.05.01
chapter4. 연산자(Operator) (2)  (0) 2017.04.12
chapter3. 상수와 형변환(Type Casting)  (1) 2017.04.06
chapter2. 변수와 자료형  (0) 2017.04.05
chapter1 Java의 시작(2)  (0) 2017.04.04

+ Recent posts