본문 바로가기

JAVA

Java & SpringBoot로 시작하는 웹 프로그래밍 : 자바 인강 - 2주차

2주차 목차

  • 조건문
  • 반복문
  • 객체 지향 입문

 

조건문

if(조건식1){

   수행문1;  // 조건식1이 '참'이면 수행문1 실행

}

else if(조건식2){

   수행문2;  // 조건식2이 '참'이면 수행문2 실행

}

else{

   수행문3;  // 위 조건에 전부 해당되지 않으면 실행

}

 

package ch02;

public class ifElseTest{

	public static void main(String[] args) {
		
		int age = 7;
		
		if(age >= 8) {
			System.out.println("학교에 다닙니다."); 
		}
		else {
			System.out.println("학교에 다니지 않습니다."); 
		}
		
		System.out.println("노는게 젤 좋아"); 
				
 	}
}

 

 

입장료를 보여주는 프로그램

package ch02;

public class ifElseIfTest{

	public static void main(String[] args) {
		
		int age = 12;
		int charge; 
		// charge 초기화 하지않은 경우 else 문 써야한다.
		
		if(age < 8) {
			charge = 1000;
			System.out.println("미 취학 아동입니다."); 
		}
		
		else if(age < 14) {
			charge = 2000;
			System.out.println("초등학생 입니다."); 
		}
		
		else if(age < 20) {
			charge = 2500;
			System.out.println("중,고등학생 입니다."); 
		}
		
		else {
			charge = 3000;
			System.out.println("일반인 입니다."); 
		}
		System.out.println("입장료는 " + charge + " 입니다."); 
		
 	}
}

 

 

if - if 문

  • 각각 두 번 체크한다.

 

else - if 문

  • if문 수행시 나머지 수행문 수행하지 않는다.

 

 

switch - case문

  • 비교 조건이 특정 값이나 문자열인 경우 사용
  • break문을 사용하여 빠져나오도록 함

 

한달이 며칠인지 알려주는 프로그램

package ch02;

import java.util.Scanner;

public class SwitchCaseTest{

	public static void main(String[] args) {
		
		Scanner scanner = new Scanner(System.in);
		int month = scanner.nextInt();
		
		int day;
		
		switch(month) {
		
			case 1: case 3: case 5: case 7: case 8: case 10: case 12:
				day = 31;
				break;
			case 2: day = 28;
				break;
			case 4: day = 30;
				break;
			case 6: day = 30;
				break;
			case 9: day = 30;
				break;
			case 11: day = 30;
				break;
			default:
				System.out.println("존재하지 않는 달입니다.");
				day = -1;
		}
		System.out.println(month+"월은 " + day +" 일입니다.");
 	}
}

 

Java 14 부터 지원 되는 Switch Expression

  • case 문에서 간단하게 쉼표(,) 로 조건 구분
  • 식으로 반환 값을 받을 수 있음, 리턴 값이 없는 경우는 오류 발생
  • break문 쓰지않고 반환값은 yield 키워드 사용
package ch02;

import java.util.Scanner;

public class SwitchCaseTest{

	public static void main(String[] args) {
		
		Scanner scanner = new Scanner(System.in);
		int month = scanner.nextInt();
		
		
		int day = switch(month) {
		
			case 1, 3, 5, 7, 8, 10, 12-> 
				31;
				
			case 2->
				28;
				
			case 4, 6, 9, 11->
				30;
				
			default-> { // 두 줄일 경우 중괄호 사용
				System.out.println("존재하지 않는 달입니다.");
				yield -1; // 반환값이 따로 있을 떄 yield 사
			}
		}; // 세미콜론 써야한다.
		
		System.out.println(month+"월은 " + day +" 일입니다.");
 	}
}

 

 

 

 

반복문

조건이 참(true)인 동안 수행문을 반복적으로 수행

 

 

while문

  • 조건이 맞지 않으면 수행하는 부분이 없고 조건의 결과가 참일때 반복 수행
  • 조건식의 결과나 변수가 참, 거짓으로 나오는 경우 유용하게 사용

 

1부터 10까지 더한 결과를 출력하는 프로그램

package ch02;

public class WhileTest{

	public static void main(String[] args) {
		
		int num = 1;
		int sum = 0; // 지역변수 초기화 해줘야한다.
		
		while( num <= 10) {
			sum += num;
			num++;
		}
		System.out.println(sum); // 1부터 10까지의 
		System.out.println(num); // 빠져나왔을때 num의 값
 	}
}

 

 

do-while문

  • 수행을 일단 한 번 하고나서 조건을 체크
  • 조건식의 결과나 변수가 true, false 인 경우 유용

 

do {

   수행문1;

} while(조건식);

   수행문2;

 

package ch02;

import java.util.Scanner;

public class DoWhileTest{

	public static void main(String[] args) {
		
		Scanner scanner = new Scanner(System.in);
		int input;
		int sum = 0;
		
		
		do {
			input = scanner.nextInt(); // 값을 일단 받기
			sum += input;
			
			input = scanner.nextInt();
		}while(input != 0);
		
		System.out.println(sum); // 0인 경우 반복문 종료
		
 	}
}

 

 

for문

  • for(초기화, 조건체크, 증감)으로 수행
  • 배열 탐색할 때 많이 사용됨

 

for ( 초기화식; 조건식; 증감식) {

 

    수행문;

 

}

 

 

1부터 10까지 더한 결과를 출력하는 프로그램

package ch02;

public class ForTest{

	public static void main(String[] args) {
		
		
		// for문으로 카운
		int count = 1;
		int sum = 0;
		
		for(int i = 0; i < 10; i++, count++) { // 식 한 번에 두 개씩 쓸 수도 있다.
			
			sum += count;
		}
		
		System.out.println(sum); 
		
		
		// while로 카운
		int num = 1;
		int total = 0;
		
		while(num <= 10) {
			
			total += num;
			num++;
		}
		System.out.println(total); 
 	}
}

 

 

무한 반복

for ( ;  ; ) {

}

 

 

중첩반복문

  • 외부 반복문과 내부 반복문 간의 변수 값 변화에 유의하여 구현학
  • 반복문 안에 반복문이 또 있는 구조

 

구구단 만들어보기 (중첩반복문, while문)

package ch02;

public class ForTest{

	public static void main(String[] args) {
		
		// for문으로 구구단 만들어보기
		int dan = 2;
		int count = 1;
		
		for( ; dan <= 9; dan++) { // 단이 증가하는 것, 내부가 수행 후 증
			
			for(count =1; count <= 9; count++) {
				System.out.println(dan + "X" + count + " = " + dan*count); 
			}
		}
		System.out.println(); // 단마다 한 줄 띄기 
		
		
		// while문으로 구구단 만들어보기
		dan = 2;
		count = 1;
		while( dan <= 9) {
			
			count = 1; // count 다시 1로 초기
			while (count <= 9) {
				System.out.println(dan + "X" + count + " = " + dan*count); 
				count++;
			}
			dan++;
		}
	}
}

 

 

중간에 멈추는 break문

  • 반복 수행을 멈추고 제어문을 빠져 나와 반복문 외부로 이동하여 수행
  •  반복문이 중첩되어 있는 경우엔 break문이 포함되어 있는 반복문만 빠져 나옴

 

1부터 숫자를 더하여 100이 넘는 순간의 그 숫자와 합 출력하는 프로그램

package ch02;

public class BreakTest{

	public static void main(String[] args) {
		
		int sum = 0;
		int num;
		
		for(num = 1; ; num++){
			
			sum += num;
			
			if( sum >= 100) 
				break; // 100보다 큰 경우 멈추기
		}
		
		System.out.println(sum); // 100이 넘는 순간 105
		System.out.println(num); // 14까지 더하면 100보다 큰 순간이다.
	}
	
	
}

 

 

continue문

  • continue 이후에는 다시 위에 있는 반복문으로 돌아감

 

1부터 100까지의 숫자 중 3의 배수 출력하는 프로그램

package ch02;

public class ContinueTest{

	public static void main(String[] args) {
		
		int num;
		
		for(num = 1; num<=100 ; num++){
			
			if( num % 3 != 0) continue;
			
			System.out.println(num); 
		}
	}	
}

 


 

객체 지향의 입문

01. 객체와 객체 지향 프로그래밍

 

객체 (Object)

  • 의사나 행위가 미치는 대상(사전적 의미)
  • 구체적, 추상적 데이터의 단위 

 

 

02. 생활 속에 객체를 찾아 클래스로 구현해 보기

 

클래스는 객체의 청사진(blueprint)이다.

클래스를 만든다는 것은 해당 객체를 추상화 하여 코딩하는 것

객체의 속성은 클래스의 멤버 변수 (member variable)로 선언함

 

String : 자바에서 문자열을 나타낼 때 제공해주는 클래스 

 

 

학생의 정보를 담고 있는 클래스를 만들고 멤버변수 선언하기

package ch02;

public class Student{

	int studentNumber; // 멤버변수
	String studentName;
	int majorCode;
	String majorName;
	int grade;
}

 

 

 

03. 함수와 메소드

함수란 (function)

  • 하나의 기능을 수행하는 일련의 코드
  • 구현된 함수는 호출하여 사용하고 호출된 함수는 기능이 끝나면 제어가 반환됨
  • 여러 곳에서 사용 가능
  • 이름, 매개 변수, 반환 값, 함수 몸체로 구성 (반환하지 않을땐 void 사용)

 

함수 선언, 호출 예제

package ch02;

public class FunctionTest{

	public static int addNum(int num1, int num2) {
		
		int result;
		result = num1 + num2;
		return result;
	}
	
	public static void sayHello(String greeting) {
		
		System.out.println(greeting);
		
	}
	
	public static int calcSum(){
		
		int sum = 0;
		int i;
		
		for(i = 0; i <= 100; i++) {
			sum += i;
		}
		return sum;
	}
	
	
	public static void main(String[] args) {
		
		int n1 = 10;
		int n2 = 20;
		
		int total = addNum(n1, n2); // 함수호출
		System.out.println(total);
		
		sayHello("안녕하세요");
		
		total = calcSum();
		System.out.println(total);
		
	}
}

 

 

함수 호출과 스택 메모리

  • 스택 : 함수가 호출 시 지역 변수가 사용하는 메모리
  • 지역변수는 그 지역에서만 쓰고 그 블록이 끝나면 자동으로 없어진다.
  • 스택 메모리는 함수의 수행이 끝나면 자동으로 반환 된다.

 

메소드 (method)

  • 객체의 기능 구현을 위해 클래스 내부에 구현되는 함수
  • 함수는 어디 속해있는게 아님 단독 모듈로 호출해서 사용하는 것이고 메소드는 클래스 안에 속해 있다. 
  • 클래스의 멤버 변수들을 활용해서 구현
  • 그 객체를 다른 객체가 사용하는 일들이 많아 호출하는 쪽 이름을 사용하는 것이 좋음

 

 

04. 객체의 속성은 멤버 변수로, 객체의 기능은 메소드로 구현한다

 

package ch02;

public class Student {
	
	public int studentID;
	public String studentName;
	public String address;
	
	public void showStudentInfo() {
		System.out.println(studentID + "학번 학의 이름은 "+ studentName+ " 이고 주소는 "+ address +"입니다.");
	}
	
	// studentName을 가져가는 함수
	public String getStudentName() {
		return studentName;
	}
	
	// 이름을 바꿀 수 있는 함수
	public void setStudentName(String name) {
		studentName = name;
		// name을 매개변수로 가져와서 studentName에 넣기
	}
	
}

 

package ch02;

public class StudentTest { // 클래스를 쓰기 위한 클래스

	public static void main(String[] args) {
		
		Student studentLee = new Student(); 
		// 생성자, Student 하나를 생성해라
		// 이렇게해서 생성된 것은 인스턴스
		// studentLee는 참조변수(생성된 인스턴스의 메모리 위치를 알려줌)
		
		studentLee.studentID = 12345; // 참조변수. 으로 멤버변수, 메소드 호출
		studentLee.setStudentName("Lee");
		studentLee.address = "서울 강남구";
		// 인스턴스의 멤버변수와 메소드로 값을 세팅
		
		studentLee.showStudentInfo();
		
		
		// 학생 한 명 더 만들기
		Student studentKim = new Student();
		studentKim.studentID = 54321;
		studentKim.studentName = "Kim";
		studentKim.address = "경기도 성남시";
		
		studentKim.showStudentInfo();

	}

}

위 코드 구조

 

05. 인스턴스 생성과 힙 메모리

 

인스턴스

자바에서 학생 클래스를 각각 생성하면

인스턴스 new 키워드에 의해 동적메모리 heap에 생성이 된다. 

 

위 코드에서 studentKim, studentLee 라는 두 개의 인스턴스에

. 찍고 studentID, studentName, address 다 따로 줬는데 (인스턴스는 각각 다른 멤버 변수 값을 가지게 된 상태) 

이게 가능한 이유는 각각이 다 다른 메모리에 위치하기 때문

 

즉, 클래스 코드는 하나지만 클래스로 부터 생성된 인스턴트는 여러 개일 수 있다.

인스턴스들은 다 다른 방을 차지하는데 그 방들이 heap 이라는 동적 메모리이다.

 

 

힙 메모리

생성된 인스턴스에 메모리를 할당 받는 것은 동적 메모리 heap이다.

필요할 때 할당 받고 다 쓰고 나면 해제를 시켜야한다.

 

Student studentLee = new Student();

타입은 Student 이고 studentLee라는 참조변수가 선언 된 것

Student()new 로 어떤 값을 할당 받은 것

 

studentLee는 지역변수고 할당된 값이 인스턴스의 주소값

 

System.out.println(studentLee);

찍어보면 이 값이 heap 메모리의 가상주소를 가리킨다.

 

 

용어 정리

  • 인스턴스 : 클래스를 new 키워드를 사용하여 메모리에 생성된 상태
  • 멤버 변수 : 클래스 안에 선언된 변수들
  • 메소드 : 멤버 변수를 기반으로 클래스가 하는 기능들 구현한 함수
  • 참조 변수 : 메모리에 생성된 인스턴스를 가리키는 변수
  • 참조값 : 생성된 인스턴스의 주소값

 

 

06. 생성자 알아보기

 

생성자

<클래스 이름>([<argument_list]} {[<statements]}

 

Student studentLee = new Student(); 에서 new Student() 가 생성자

studentLee는 인스턴스를 가르키는 참조변수

 

  • 초기화 하기 위해 사용
  • Student 같은 객체인 경우에는 항상 생성자 쓰기
  •  heap 메모리에 생성된다.
  •  new 키워드와 같이 쓴다
  • 호출하기 위해서 쓰는 것이 아니라 객체를 생성(초기화)을 하기 위해서만 사용
  • 반환값이 없고 생성자의 이름은 클래스 이름과 동일
  • 외부에서 접근 가능하지만 private으로 내부에서 쓰는 생성자도 있다
  • 클래스에는 하나 이상의 생성자가 존재해야한다

 

기본 생성자 (default constructor)

  • 생성자를 선언하지 않은 경우 기본 생성자가 만들어진다.
  • 매개변수도 없고 구현부도 없다
  • 컴파일러가 자동으로 만들어준다.

 

 

Student.java

package ch02;

public class Student {
	
	public int studentNumber;
	public String studentName;
	public String grade;
	
	public String showStudentInfo() {
		
		return studentName + "학생의 학번은 " + studentNumber + "이고 " + grade + " 학년 입니다.";
	}
		
}

 

StudentTest.java

package ch02;

public class StudentTest {

	public static void main(String[] args) {
		
		Student studentLee = new Student();
		
		System.out.println(studentLee.showStudentInfo());

	}
}

 

실행 결과

이름은 객체이기 때문에 null로 초기화 int는 0으로 초기화

아무런 정보도 주지 않기 때문에 초기화 된 값이 출력됨

 


생성자를 만든 경우

 

Student.java

package ch02;

public class Student {
	
	public int studentNumber;
	public String studentName;
	public int grade;
	
	public Student(){} // 디폴트 생성자를 직접 선언
	// Student studentLee = new Student();의 경우 이미 생성자가 존재해서 디폴트 생성자를 직접 선언해줘야함
	
	
	public Student(int studentNumber, String studentName, int grade) { // 생성자 직접 만들기
		
		// Student를 생성할때 학생의 이름, 학번, 학년을 매개변수로 받아서 초기화
		
		this.studentNumber = studentNumber; // 멤버변수에에 this 붙이기(매개변수는 그대로 씀), 오버로딩
		this.studentName = studentName;
		this.grade = grade;
		
	}
	
	public String showStudentInfo() {
		
		return studentName + "학생의 학번은 " + studentNumber + "이고 " + grade + " 학년 입니다.";
	}
		
}

StudentTest.java

package ch02;

public class StudentTest {

	public static void main(String[] args) {
		
		Student studentLee = new Student();
		// 디폴트 생성자이기 때문에 생성자 존재시 오류
		// 디폴트 생성자를 만들면 오류 발생안함
		
		studentLee.grade = 123; 
		// 이런식으로 써도 괜찮고 생성자가 존재한다면 밑처럼 생성자를 써도됨
		System.out.println(studentLee.showStudentInfo());
		
		
		Student studentKim = new Student(123456, "Kim", 3);
		System.out.println(studentKim.showStudentInfo());

	}

}

 

 

 

07. 여러가지 생성자를 정의하는 생성자 오버로딩

 

생성자 오버로딩

  • 여러가지 생성자를 매개변수만 다르게 해서 같이 정의할 수 있다.
  • 메소드도 마찬가지로 생성자 오버로딩, 메소드 이름은 같고 매개변수만 다르게 해서 오버로딩

this.userName = userName;

this가 붙은건 멤버변수, 뒤에 있는 그냥은 매개변수

 

 

08. 복습 (객체 구현하기)

1. 키가 180이고 몸무게 78키로인 남성, 이름 Tomas, 나이 37세

 

코드

Person.java

package ch02;

public class Person {
	
	public int height;
	public int weight;
	public String name;
	public int age;
	public String gender;
	
	
	public Person(int height, int weight, String name, int age, String gender) {
		
		this.height = height;
		this.weight = weight;
		this.name = name;
		this.age = age;
		this.gender = gender;
	}
	
	public String showInfo() {
		
		return "키가 "+ height + " 이고 몸무게 " + weight + "인 남성, 이름은 " + name + ", 나이는 " + age +"세";
	}
}

PersonTest.java

package ch02;

public class PersonTest {

	public static void main(String[] args) {
		
		Person person = new Person(180, 78, "Tomas", 37, "남성");
		
		System.out.println(person.showInfo());

	}
}

 

결과

 

 

2. 음식점에 배달 주문 (내용을 입력받아 내용 출력하기)

  • 주문 접수 번호 : 202011020003
  • 주문 핸드폰 번호 : 01023450001
  • 주문 집 주소 : 서울시 강남구 역삼동 111-333
  • 주문 날짜 : 20201102
  • 주문 시간 : 130258
  • 주문 가격 : 35000
  • 메뉴 번호 : 0003

 

코드

Order.java

package ch02;

public class Order {
	
	public String orderNum;
	public int phoneNum;
	public String address;
	public int orderDate;
	public int orderTime;
	public int price;
	public int menuNum;
	
	
	public Order(String orderNum, int phoneNum, String address, int orderDate, int orderTime, int price, int menuNum) {
		
		this.orderNum = orderNum;
		this.phoneNum = phoneNum;
		this.address = address;
		this.orderDate = orderDate;
		this.orderTime = orderTime;
		this.price = price;
		this.menuNum = menuNum;
	}
	
	public String showPersonInfo(){
		
		return("주문 접수 번호 : " + orderNum + "\n주문 핸드폰 번호 : " + phoneNum + "\n주문 집 주소 : " + address + "\n주문 날짜 : " + orderDate + "\n주문 시간 : " + orderTime + "\n주문 가격 : " + price + "\n메뉴 번호 : " + menuNum);

	}
}

OrderTest.java

package ch02;

import java.util.Scanner;

public class OrderTest {

	public static void main(String[] args) {
		
		Scanner scanner = new Scanner(System.in);
		
		System.out.print("주문 접수 번호 : ");
		String orderNum = scanner.nextLine();
		System.out.print("핸드폰 번호 : ");
		int phoneNum = scanner.nextInt();
		scanner.nextLine(); // 개행문자(엔터)를 제거하기 위해 추가
		System.out.print("주문 집 주소 : ");
		String address = scanner.nextLine();
		System.out.print("주문 날짜 : ");
		int orderDate = scanner.nextInt();
		System.out.print("주문 시간 : ");
		int orderTime = scanner.nextInt();
		System.out.print("주문 가격 : ");
		int price = scanner.nextInt();
		System.out.print("메뉴 번호 : ");
		int menuNum = scanner.nextInt();
		
		Order person = new Order(orderNum, phoneNum, address, orderDate, orderTime, price, menuNum);
		
		System.out.print(person.showPersonInfo());
		
	}

}

 

결과

주소를 입력 받고 오류가 계속 떴음

이유를 찾아보니 Scanner.nextInt 메소드는 사용자의 입력의 가장 마지막 개행 문자(엔터)를 제거하지 않음

개행문자(엔터)는 다음에 호출된 Scanner.nextLine 메소드의 입력으로 처리된다.

 

해결 방법 : 

scanner.nextLine(); // 개행문자(엔터)를 제거하기 위해 추가 하였다

 

 

 

 

 

2주차 후기

진도는 수월하게 나갔는데 마지막 복습 과제에서

오류가 발생하여 시간을 많이 소모하였다 ₍ᐢɞ̴̶̷.̮ɞ̴̶̷ᐢ₎ ㅋ..

콘솔 입력에 대해 제대로 배우지 않은 상태에서

무작정 과제 2번을 하려니까 꽤나 어려움을 느껴 수업때 한 코드를 참고하였고

배열이나 반복문으로도 구현 가능한 부분인거 같은데

조건이 딱히 없어 둘 다 사용하지 않았다.