1.  객체 지향 프로그래밍  Object Oriented Programming

🚀  소프트웨어를 개발할 때 부품에 해당하는 객체들을 먼저 만들고, 이 객체들을 하나씩 조립해서 완성된 프로그램을 만드는 기법

  ⚒️  객체지향 이론 기본 개념 : 실제 세계는 사물(객체)로 이루어져 있으며, 발생하는 모든 사건들은 사물간의 상호작용.

  ⚒️  발전 단계 : 기본자료형  →  배열  →  구조체  →  클래스

  • 구조체는 서로 다른 타입도 하나에 묶을 수 있도록 함
  • 구조체가 발전된 형태(함수까지 포함)가 클래스
70년대 -  C, 변수와 함수, 구조체
80년대 -  C++, 변수와 함수, 구조체, 클래스
90년대 -  Java, only 클래스만… 하지만 클래스안에 변수와 메서드가 있음

 

 

​  ⚒️  주요특징

 

    1.  캡슐화 Encapsulation

       

        -  객체의 데이터(필드), 동작(메소드)을 하나로 묶고 실제 구현 내용을 외부에 감추는 것

        -  외부 객체는 객체 내부의 구조를 알지 못하며 객체가 노출해서 제공하는 필드와 메소드만 이용할 수 있다

        -  외부의 잘못된 사용으로 인해 객체가 손상되지 않도록 하는 데 의의가 있다

        -  자바 언어는 접근 제한자를 사용하여 캡슐화된 멤버를 노출시킬 것인지 숨길 것인지 결정

 

    2.  상속 Inheritance

 

     

-  부모 객체가 자기가 가지고 있는 필드와 메소드를 자식 객체에게 물려줌

-  코드의 재사용성을 높여준다

-  유지 보수 시간을 최소화 시켜 준다

 

   

 

    3.  다형성 Polymorphism

       

 

-  사용 방법은 동일하지만 실행 결과가 다양하게 나오는 성질을 말함

-  자동 타입 변환과 재정의 기술이 필요함  ➡️  상속과 인터페이스 구현을 통해 얻어짐

 

 

 

 

 


1)  객체란 ?

  👾  물리적으로 존재하거나 개념적인 것 중에서 다른 것과 식별 가능한 것

  👾  객체는 속성과 동작으로 구성   ex. 사람은 이름, 나이 등의 속성과 웃다, 걷다 등의 동작이 있음

         ➡️  자바는 이러한 속성과 동작을 각각 '필드 field' '메소드 method' 라고 부름

  👾  현실 세계의 객체를 소프트웨어 객체로 설계하는 것을 객체 모델링 object modeling 이라고 함

 

객체의 상호작용
  • 현실 세계에서 일어나는 모든 현상은 객체와 객체 간의 상호작용으로 이루어져 있다.
  • 객체 지향 프로그램에서도 객체들은 다른 객체와 서로 상호작용하면서 동작함.
  • 객체들 사이의 상호작용 수단은 메소드. 객체가 다른 객체의 기능을 이용할 때 이 메소드를 호출한다.
// 메소드 호출 형식
메소드(매개값1, 매개값2, ...);
  • 메소드 이름과 함께 전달하고자 하는 데이터를 괄호() 안에 기술하는데, 이러한 데이터를 매개값이라고 함.
  • 리턴값은 메소드의 실행의 결과이며 호출한 곳으로 돌려주는 값

 

객체 간의 관계

 

  1.  집합 관계  -  완성품과 부품의 관계를 말함. 

        ex.  자동차는 엔진, 타이어, 핸들 등으로 구성

  2. 사용 관계  -  다른 객체의 필드를 읽고 변경하거나 메소드를 호출하는 관계

        ex. 사람이 자동차에 달린다, 멈춘다 등의 메소드를 호출

  3. 상속 관계  -  부모와 자식 관계.

        ex. 자동차가 기계의 특징(필드, 메소드)을 물려받는다면 기계(부모)와 자동차(자식)는 상속 관계에 있음


2)  객체와 클래스

🚀  클래스 Class  -  객체를 생성하기 위한 설계도

  • 클래스로부터 생성된 객체를 해당 클래스의 '인스턴스 instance' 라고 부른다
  • 클래스로부터 객체를 만드는 과정을 인스턴스화라고 함
  • 동일한 클래스로부터 여러 개의 인스턴스를 만드는 것 = 동일한 설계도로 여러 대의 자동차를 만드는 것

 ⚒️  ​객체는 모든 인스턴스를 대표하는 포괄적인 의미를 갖고 있으며,  인스턴스는 어떤 클래스로부터 만들어진 것인지를 강조하는 구체적인 의미를 갖고 있다.

 


3)  객체 생성과 클래스 변수 

 🚀  클래스로부터 객체를 생성하려면 객체 생성 연산자인 'new' 가 필요

 🚀  new 연산자 뒤에는 생성자 호출 코드가 오는데, 클래스() 형태를 가진다.

 🚀  객체를 생성시킨 후 객체의 주소를 리턴하기 때문에 클래스 변수에 다음과 같이 대입할 수 있다.

클래스 변수 = new 클래스();

 

사용 예제
  • Student 클래스를 선언하고 StudentExample 클래스의 main() 메소드에서 Student 객체를 생성
public class Student {}
public class StudentExample {
    public static void main(String[] args) {
        Student s1 = new Student();
        System.out.println("s1 변수가 Student 객체를 참조합니다.");
        
        Student s2 = new Student();
        System.out.println("s2 변수가 또 다른 Student 객체를 참조합니다.");
    }
}

 

💡  클래스의 두 가지 용도
      - 라이브러리(library) 클래스 : 실행할 수 없으며 다른 클래스에서 이용하는 클래스
      - 실행 클래스 : main() 메소드를 가지고 있는 실행 가능한 클래스
      - Student는 라이브러리 클래스이고 StudentExample은 실행 클래스라고 볼 수 있음. 일반적으로 자바 프로그램은 하나의 실행 클래스와 여러 개의 라이브러리 클래스들로 구성된다. 

 


 4)  클래스의 구성 멤버

🚀  클래스 선언에는 객체 초기화 역할을 담당하는 생성자와 객체에 포함될 필드와 메소드를 선언하는 코드가 포함된다. 

 

  1.  필드 field 

     -  선언 형태는 변수 선언과 비슷하지만 쓰임새는 다름

 

  2. 생성자 constructor 

     -  new 연산자로 객체를 생성할 때 객체의 초기화 역할을 담당.

     -  선언 형태는 메소드와 비슷하지만, 리턴 타입이 없고 이름은 클래스 이름과 동일

 

  3. 메소드 method

     -  다른 프로그램 언어에서는 함수라고 하기도 하는데, 객체 내부의 함수는 메소드라고 부름

     -  메소드는 객체와 객체간의 상호 작용을 위해 호출

 


5)  필드 선언과 사용

타입 필드명 [ = 초기값];

 

  👾  반드시 클래스 블록에서 선언되어야만 필드 선언이 된다.

  👾  필드명은 첫 문자를 소문자로 하되, 캐멀 스타일로 작성하는 것이 관례.

public class Car {
    String model = "그렌저";  // 고유 데이터 필드
    int speed = 300;        // 상태 데이터 필드
    boolean start = true;   // 상태 데이터 필드
    Tire tire = new Tire(); // 부품 객체 필드
}

 

   👾  초기값을 제공하지 않을 경우 필드는 객체 생성 시 자동으로 기본값으로 초기화된다.

public class Car {
    String model;  // null
    int speed;     // 0
    boolean start; // false
    Tire tire;     // null
}

 

필드 사용

 

   👾  필드를 사용한다는 것은 필드값을 읽고 변경하는 것을 말함

   👾  필드는 객체의 데이터이므로 객체가 존재하지 않으면 필드도 존재하지 않음

   👾  필드는 객체 내부의 생성자와 메소드 내부에서 사용할 수 있고, 객체 외부에서도 접근해서 사용할 수 있다.

 

  ⚡️  객체 내부에서는 단순히 필드명으로 읽고 변경 가능

  ⚡️  외부 객체에서는 참조 변수와 도트(.) 연산자를 이용해서 필드를 읽고 변경해야 함

  ⚡️  도트는 객체 접근 연산자로, 객체가 가지고 있는 필드나 메소드에 접근하고자 할 때 참조 변수 뒤에 붙임

 

💡  참조변수에는 하나의 값(주소)만이 저장될 수 있으므로 둘 이상의 참조변수가 하나의 인스턴스를 가리키는(참조하는) 것은 가능하지만 하나의 참조변수로 여러 개의 인스턴스를 가리키는 것은 불가능

 

필드 VS 변수
구분 필드 (로컬) 변수
선언 위치 클래스 선언 블록 생성자, 메소드 선언 블록
존재 위치 객체 내부에 존재 생성자, 메소드 호출 시에만 존재
사용 위치 객체 내,외부 어디든 사용 생성자, 메소드 블록 내부에서만 사용

 

사용 예제
public class Car {
    boolean powerOn; // 시동
    String color; // 차량의 색상
    int wheel; // 바퀴의 수
    int speed; // 속력
    boolean wiperOn; // 와이퍼

    void power() {
        powerOn = !powerOn; // 시동 메서드
    }
    void speedUp(){
        speed++; // 액셀 메서드
    }
    void sppedDown() {
        speed--; // 브레이크 메서드
    }
    void wiper(){
        wiperOn = !wiperOn; // 와이퍼 메서드
    }
}
public class CarTest {
    public static void main(String[] args) {
        Car mycar; // 클래스의 객체를 참조할 수 있는 참조변수 선언
        mycar = new Car(); // 클래스의 객체를 생성하고 객체의 주소를 참조변수에 저장

        System.out.println("시동 처음 초기화 : " + mycar.powerOn);
        System.out.println("차의 색상 초기화 : " + mycar.color);
        System.out.println("바퀴의 수 초기화 : " + mycar.wheel);
        System.out.println("속력 초기화 : " + mycar.speed);
        System.out.println("와이퍼 작동 초기화 : " + mycar.wiperOn);

        mycar.power(); // 시동 메서드 실행
        System.out.println("시동 메서드 동작 : " + mycar.powerOn);
        mycar.power();
        System.out.println("시동 메서드 다시 동작 : " + mycar.powerOn);

        mycar.color = "black"; // 색상 변수에 black 대입
        System.out.println("현재 차의 색상 : " + mycar.color);

    }
}
시동 처음 초기화 : false
차의 색상 초기화 : null
바퀴의 수 초기화 : 0
속력 초기화 : 0
와이퍼 작동 초기화 : false
시동 메서드 동작 : true
시동 메서드 다시 동작 : false
현재 차의 색상 : black
 
 

 

 

*  내용 참고 - 학원강의 및 책 '이것이 자바다'

 


1.  JVM 메모리 구조

1)  메서드 영역 (method area)

  • 프로그램 실행 중 어떤 클래스가 사용되면, JVM은 해당 클래스파일을 분석하여 이곳에 저장한다.

2)  힙(heap)

  • 인스턴스가 생성되는 공간.

3)  호출스택(call stack 또는 execution stack)

  • 메서드의 작업에 필요한 메모리 공간을 제공한다. 메서드가 호출되면, 호출된 메서드를 위한 메모리가 할당되며 이 메모리는 메서드가작업을 수행하는 동안 지역변수들과 연산의 중간결과 등을 저장하는데 사용된다.
  • 메서드가 작업을 마치면 할당되었던 메모리공간은 반환되어 비워진다.
  • 각 메서드를 위한 메모리상의 작업공간은 서로 구별되며, 첫 번째로 호출된 메서드를 위한 작업공간이 호출스택의 맨 밑에 마련되고, 첫 번째 메서드 수행 중에 다른 메서드를 호출하면 첫 번째 메서드의 바로 위에 두 번째로 호출된 메서드를 위한 공간이 마련된다.
💡  후입선출 구조 (LIFO : Last-in, First-out)
     -  제일 상위에 위치하는 메서드가 현재 실행중인 메서드 
     -  이 메서드가 끝나야 먼저 호출된 메서드가 다시 실행하게 됨
     -  반환타입이 있는 메서드는 종료되면서 결과값을 자신을 호출한 메서드(caller)에게 반환한다
     -  caller는 넘겨받은 반환값으로 수행을 계속 진행하게 된다

public class MyMethod_08 {

	// main() -> firstMethod() -> secondMethod()
	// 메모리 구조상 secondMethod가 가장 위에 쌓이고, main이 가장 아래에 깔린다고 생각하면 됨.

	public static void main(String[] args) {
	     System.out.println("main(String[] args)이 시작되었음."); //1
	     firstMethod(); // 이 메서드를 호출함. 리턴 값이 있든 없든 이 메서드가 끝나야지 다음 줄로 넘어감.
	     System.out.println("main(String[] args)이 끝났음.");//6
	}
	
    static void firstMethod() {
    	System.out.println("firstMethod()이 시작되었음."); //2
        secondMethod(); // 이 메서드가 끝나야지 다음 줄로 넘어감.
        System.out.println("firstMethod()이 끝났음.");//5
    }
    
    static void secondMethod() {
    	System.out.println("secondMethod()이 시작되었음."); //3
    	System.out.println("secondMethod()이 끝났음."); //4
    }
}

 

 

​2.  오버로딩(overloading)

🚀  한 클래스 내에 같은 이름의 메서드를 여러 개 정의하는 것을 말함

🚀  오버로딩의 조건  1) 메서드 이름이 같아야 한다. 2) 매개변수의 개수 또는 타입이 달라야 한다.

      ⚡️  매개변수에 의해서만 구별될 수 있으므로 반환 타입은 오버로딩을 구현하는데 아무런 영향을 주지 못한다.

장점
  • 메서드의 이름만 보고도 같은 기능을 하겠다는 예측을 쉽게 할 수 있다.
  • 메서드의 이름을 절약할 수 있음   ➡️  하나의 이름으로 여러개의 메서드를 정의할 수 있어 이름 짓는데 고민이 줄고, 동시에 사용되었어야 할 메서드 이름을 다른 메서드의 이름으로 사용할 수 있다.
public class MyMethod_06 {

	public static void main(String[] args) {
		
		printGreet(); // 안녕하세요
		printGreet("안녕~!"); // 안녕~!
		printGreet("한수", "잘 지내셨나요?"); // 한수님! 잘 지내셨나요?
		printGreet(3); // 안녕하세요. 3번째 보는거네요.
	}
	
	public static void printGreet() {
		System.out.println("printGreet() 메서드가 실행됩니다.");
		System.out.println("안녕하세요.");
	}
	
	public static void printGreet(String greeting) {
		// 같은 이름의 메서드가 있으나 매개변수가 없음
		System.out.println("printGreet(String greeting) 메서드가 실행됩니다.");
	    System.out.println(greeting);
	}
	
	public static void printGreet(String name, String greeting) {
		// 매개변수가 문자열인 메서드가 있으나 갯수가 다름
		System.out.println("printGreet(String name, String greeting) 메서드가 실행됩니다.");
	    System.out.println(name + "님! "+ greeting);
	}
	
    public static void printGreet(int cont) {
    	// 매개변수가 하나인 메서드가 있으나 데이터 타입이 다름
        System.out.println("printGreet(int cont) 메서드가 실행됩니다.");
        System.out.println("안녕하세요. " + cont + "번째 보는거네요.");
    }
}
 


3.  응용 문제

1)  암산 트레이닝

public class Ex_02_01 {
    static Scanner scanner= new Scanner(System.in);
   
    static boolean confirmRetry() {
    	int numb;
    	do {
    		System.out.print("다시 한 번? <Yes-1/No-0> : ");
    		numb = scanner.nextInt();
    	} while(numb != 0 && numb != 1);
    	return numb == 1;
    }

	public static void main(String[] args) {
		Random random = new Random();
		
		System.out.println("암산 트레이닝!!");
	    do {
	    	int x = random.nextInt(90)+10;
	    	int y = random.nextInt(90)+10;
	    	int z = random.nextInt(90)+10;
	    	
	    	while (true) {
	    		System.out.print(x + " + " + y + " + " + z + " = ");
	    		int k = scanner.nextInt();
	    		if (k == x + y + z) { // 정답
	    			break;
	    		}	
	    		else if ( k > x + y + z ) {
	    			System.out.println("down");
	    		}
	    		else {
	    			System.out.println("up");
	    		}
	    		System.out.println("틀렸습니다!!");
	    	}
	    } while(confirmRetry());
	}
}

 2)  학생 조사

public class Ex_02_02 {

	static Scanner scanner = new Scanner(System.in);
	static boolean run = true; 
    static int studentNum = 0; 
    static int[] scores = null;
	
	public static void main(String[] args) {
		
        while (run) {
            System.out.println("-----------------------------------------------------");
            System.out.println("1.학생수 | 2.점수입력 | 3.점수리스트 | 4.분석 | 5.종료");
            System.out.println("-----------------------------------------------------");
            System.out.print("선택> ");
            int selectNo = scanner.nextInt();
          
            if (selectNo == 1) {
            	inputStudentNum();
            } else if (selectNo == 2) {
            	inputScores();
            } else if (selectNo == 3) {
                printScores();
            } else if (selectNo == 4) {
                printAnalysis();
            } else if (selectNo == 5) {
                setRun();
            }
        }
        System.out.println("프로그램 종료");
	}
	
	public static void inputStudentNum() {
		System.out.print("학생수> ");
        studentNum = scanner.nextInt();
        scores = new int[studentNum];
        System.out.println(Arrays.toString(scores));
	}
	
	public static void inputScores() {
		for(int i = 0; i < scores.length; i++) {
        	System.out.print("scores["+i+"] : ");
        	scores[i] = scanner.nextInt();
		}
	}
	
	public static void printScores() {
		for(int i = 0; i < scores.length; i++) {
            System.out.println("score["+i+"] : " + scores[i]);
    	}
	}
	
	public static void printAnalysis() {
		int max = 0;
    	int sum = 0;
    	double avg = 0;
    	
    	for(int i = 0; i < scores.length; i++) {
    		max = (max < scores[i]) ? scores[i] : max;
    		sum += scores[i];
			}
		    avg = (double) sum / studentNum;
		    System.out.println("최고 점수: " + max);
    		System.out.println("평균 점수: " + avg);
	}
	
	public static void setRun() {
		run = false;
	}
}
 

 3)  login & logout

  • login() 메서드와 logout() 메서드를 선언
  • login() 메서드를 호출할 때는 매개값으로 id와 passwd를 제공하고, logout() 메서드는 id만 매개값으로 제공
  • login() 메서드는 매개값 id가 "admin", 매개값 password가 "1234"일 경우에만 true로 리턴하고 그외의 값일 경우에는 false를 리턴 
  • logout() 메서드는 "admin 아이디가 로그아웃 되었습니다."가 출력
public class Ex_02_04 {
	
	static Scanner scanner = new Scanner(System.in);
	
	public static boolean login(String id, String password) {
		System.out.print("아이디를 입력해 주세요. >> ");
        String inputId = scanner.nextLine();
        
        
        System.out.print("비밀번호를 입력해 주세요. >> ");
        String inputPw = scanner.nextLine();
        
        return inputId.equals("admin") && inputPw.equals("1234");
	}
	
	public static void logout(String id) {
		System.out.println(id + "가 로그아웃 되었습니다.");
	}

	public static void main(String[] args) {

        boolean result = login("",""); // true대신 login()호출;
         if (result) {
             System.out.println("로그인 되었습니다.");
             logout("admin");
             //logout() 호출;
         }
         else {
             System.out.println("id 또는 password가 올바르지 않습니다.");
         }
         
	}
}
 

 

*  내용 참고 : 학원강의 및 자바의정석 3rd

 


Method 함수(function) 

👩🏻‍💻  특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것

👩🏻‍💻  기본적으로 수학의 함수와 유사하며, 어떤 값을 입력하면 이 값으로 작업을 수행해서 결과를 반환

👩🏻‍💻  main 메서드는 '규칙'. 이 메서드 안에 실행되기를 기다리는 로직을 위치시켜야 한다. 

1)  메서드의 장점과 작성지침

  · 반복적인 코드를 줄이고 코드의 관리가 용이.

  · 반복적으로 수행되는 여러 문장을 메서드로 작성.

  · 하나의 기능을 위해 작성한 여러 코드를 하나의 단어로 표현할 수 있음. (추상화)

  · 하나의 메서드는 한 가지 기능만 수행하도록 작성하는 것이 좋음.

  · 메서드는 특정 동작을 하는 코드이기 때문에 이름을 동사로 시작   ex. getAge ()


2)  메서드 용어

  · 인수 (argument) : 메서드에 전달할 입력(input)을 의미

  · 매개변수 (parameter) : 인수를 받아서 저장하는 변수를 의미

  · 반환값 (return) : 메서드의 출력(output)을 의미. 

      ⚡️  return의 기능 1) 값을 반환  2) 함수를 종료 (반복문의 break와 비슷) 

  · 메서드 호출 : 메서드를 실제로 사용하는 것을 의미

 

사용 예제

 

   📍  3명의 신장, 체중, 나이의 최대값을 구해서 표시
         ✔️  메서드를 만들면 1) 소스가 줄어들어서 main 메서드의 기본 로직을 읽기 쉽고 2) 재사용을 할 수 있다

public class MyMethod_01 {

    static Scanner scanner = new Scanner(System.in);
    static int getMax(int a, int b, int c) { // a,b,c의 최대값을 반환
    	int max = a;
    	if(b > max) max = b;
    	if(c > max) max = c;
    	return max;
    }
    
    static void inputData(int[] height, int[] weight, int[] age) {
    	  for (int i = 0; i < 3; i++) {
  	    	System.out.print("[" + (i+1) + "] ");
  	    	System.out.print("신장: ");  height[i] = scanner.nextInt();
  	    	System.out.print("   체중: "); weight[i] = scanner.nextInt();
  	        System.out.print("   나이: ");  age[i]  = scanner.nextInt();
  	    }
    }

	public static void main(String[] args) {
		
		// 3명의 신장, 체중, 나이의 최대값을 구해서 표시.
		int[] height = new int[3];  // 신장
		int[] weight = new int[3];  // 체중
		int[] age = new int[3];     // 나이
		
		inputData(height, weight, age);
	    
/*	    // 신장의 최대값을 구한다
	    int maxHeight = height[0];
	    if (height[1] > maxHeight) maxHeight = height[1];
	    if (height[2] > maxHeight) maxHeight = height[2];
	    
	    // 체중의 최대값을 구한다
	    int maxWeight = weight[0];
	    if (weight[1] > maxWeight) maxWeight = weight[1];
	    if (weight[2] > maxWeight) maxWeight = weight[2];
	    
	    // 나이의 최대값을 구한다
	    int maxAge = age[0];
	    if (age[1] > maxAge) maxAge = age[1];
	    if (age[2] > maxAge) maxAge = age[2]; */
	    
	    int maxHeight = getMax(height[0], height[1], height[2]);  // 신장의 최대값
	    int maxWeight = getMax(weight[0], weight[1], weight[2]);  // 체중의 최대값
	    int maxAge = getMax(age[0], age[1], age[2]);  // 나이의 최대
	    
	    System.out.println("신장의 최대값은 " + maxHeight + "입니다." );
	    System.out.println("체중의 최대값은 " + maxWeight + "입니다." );
	    System.out.println("나이의 최대값은 " + maxAge + "입니다." );		

	}
}
 
사용 예제 2
public class MyMethod_03 {
	
	static int getMax(int a, int b) { // a,b의 최대값을 반환
		// return이 여러번 나와도 된다.
	    System.out.println("함수 시작");
	    if(a>b) 
	    	return a;
	    else
	    	return b;
	    // System.out.println("함수 종료") -> return 때문에 함수가 종료되기 때문에 출력되지 않음.
	}

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		
		System.out.print("정수 a : ");
		int a = scanner.nextInt();
		System.out.print("정수 b : ");
		int b = scanner.nextInt();
		
		System.out.println("최대값은 " + getMax(a,b) + "입니다.");
	    scanner.close();
	}
}

 


 3)  메서드의 선언과 구현

  🚀  메서드는 크게 두 부분 '선언부(header, 머리)'와 '구현부(body, 몸통)'로 이루어져 있다.

반환타입 메서드이름 (타입 변수명, 타입 변수명, ...)
{
  // 메서드 호출시 수행될 코드
}
int add (int a, int b) {
    int result = a + b ;
    return result; // 호출한 메서드로 결과를 반환한다.
}

 

메서드 선언부
(method declaration,
method header)
- '메서드의 이름'과 '매개변수 선언' 그리고 '반환타입'으로 구성되어 있다.
- 메서드가 작업을 수행하기 위해 어떤 값들을 필요로 하고 작업의 결과로 어떤 타입의 값을 반환하는지에 대한 정보를 제공
매개변수 선언
(prameter declaration)
- 매개변수는 메서드가 작업을 수행하는데 필요한 값들(입력)을 제공받기 위한 것이며, 필요한 값의 개수만큼 변수를 선언.
- 각 변수 간의 구분은 쉼표 ',' 를 사용. 두 변수의 타입이 같아도 변수의 타입을 생략하는 것 불가.
  ex. int add ( int x, y) {...}  // 에러. 매개변수 y의 타입이 없다.
메서드의 이름
(method name)
- 특정 작업을 수행하므로 메서드의 이름은 'add' 처럼 동사인 경우가 많다.
반환타입
(return type)
- 메서드의 작업수행 결과(출력)인 '반환값(return value)'의 타입을 적는다.
- 반환값이 없는 경우 'void'
메서드의 구현부
(method body)
- 메서드의 선언부 다음에 오는 괄호{}를 '메서드의 구현부'라고 .
- 메서드를 호출했을 때 수행될 문장들을 넣는다.
return 문 - 메서드의 반환타입이 'void'가 아닌 경우, 구현부{} 안에 'return 반환값;'이 반드시 포함되어 있어야 한다.
- 이 문장은 반환값을 호출한 메서드로 전달.
- 이 값의 타입은 반환타입과 일치하거나 적어도 자동 형변환이 가능한 것이어야 한다.
- 단 하나의 값만 반환할 수 있음.
지역변수
(local variable)
- 메서드 내에 선언된 변수들은 그 메서드 내에서만 사용할 수 있으므로 서로 다른 메서드라면 같은 이름의 변수를 선언해도 된다.
- 이처럼 메서드 내에 선언된 변수를 '지역변수'라고 한다.
 

public class ExMethod_02 {

	public int add(int a, int b) {
		int c = a + b;
		return c;
		// return 다음에 위치하는 데이터는 반드시 메서드의 리턴 타입과 일치해야 함.
		// return 3.5; // 리턴 타입과 다른 데이터형을 반환하면 오류가 발생. (자동 형변환은 가능)
	}

	public static void main(String[] args) {
	     int numb1 = 10;
	     int numb2 = 20;
	     int result = 0;
	     
	     ExMethod_02 method = new ExMethod_02();
	     result = method.add(numb1, numb2);
	     System.out.println("두수의 합은 " + result); // 메서드의 반환 값을 저장해서 출력.
	     System.out.println("두수의 합은 " + method.add(numb1, numb2)); // 메서드의 반환 값을 바로 출력
		
	}
}

 


4)  메서드의 호출

인자(argument)와 매개변수(parameter)
int result = add(1,2,3);    // 에러. 메서드에 선언된 매개변수의 개수가 다름 
int result = add(1.5, 2.3); // 에러. 메서드에 선언된 매개변수의 타입이 다름

 

    - 인자의 개수와 순서는 호출된 메서드에 선언된 매개변수와 일치해야 한다.

    - 인자는 메서드가 호출되면서 매개변수에 대입되므로, 인자의 타입은 매개변수의 타입과 일치하거나 자동형변환이 가능한 것이어야 함.

 

반환 타입

    - 반환타입이 void가 아닌경우, 메서드가 작업을 수행하고 반환한 값을 대입연산자로 변수에 저장하는 것이 보통이지만, 저장하지 않아도 문제가 되지 않는다.

 

메서드의 실행흐름
  • main 메서드에서 메서드 getAge를 호출
  • 호출시 지정한 인자들이 메서드 getAge의 매개변수 a,b에 각각 복사(대입) 
  • 메서드 getAge의 괄호 {} 안에 있는 문장들이 순서대로 수행
  • 메서드 getAge의 모든 문장이 실행되거나 return문을 만나면, 호출한 메서드(main메서드)로 되돌아와서 이후의 문장들을 실행

 

⚒️   메서드 호출방식

  A.  값에 의한 호출

  • 값에 의한 메서드 호출 방식은 메서드 호출 시에 값이 복사되어 전달
  • 메서드의 매개변수 타입이 '기본형 데이터'일 때 값에 의한 호출을 함.
💡  값 형식 (Value Type)

     -  변수가 값을 담은 데이터 형식, 스택 메모리 영역과 관련.

     -  코드 블록 안에서 생성된 모든 값 형식의 변수들은 프로그램 실행이 중괄호 "}"를 만나면 메모리에서 제거

public class CallByValue {

    static public int increase(int n) {
    	++n;
    	return n;
    }

	public static void main(String[] args) {
		int var1 = 100;
		int result = increase(var1);
		System.out.println("var1: " + var1 + ", result: " + result);		
	}
}

 

  • 메서드 increase() 호출 시에 n이라는 매개변수가 메모리에 생성되어 var1의 값인 100 이 복사되어 처리
  • 메서드 실행이 종료되면 매개변수 n은 메모리에서 소멸
  • 이 처럼 값에 의한 호출은 호출시 매개변수로 전달되는 값이 복사되어 전달. 따라서 var1의 값은 변하지 않음

 

B.  참조에 의한 호출

  • 매개변수의 타입이 참조형 타입일 때 사용, 참조에 의한 호출은 메서드 호출 시 참조 데이터의 위치가 매개변수에 전달
  • 값에 의한 호출은 메모리에 동일한 값을 복사 후 사용하지만 참조에 의한 호출은 메모리의 주소를 넘기기 때문에 값을 복사하지 않음
💡  참조 형식 Reference Type

       - 변수가 값 대신 값이 있는 곳의 위치(참조)를 담는 데이터 형식, 힙 메모리 영역과 관련

       - 힙 영역에 데이터를 저장하고, 스택 영역에는 데이터가 저장된 힙 메모리의 주소를 저장

       - 가비지 컬렉터가 프로그램 뒤에 숨어 동작하면서 힙에 더 이상 사용하지 않는 객체가 있으면 그 객체를 쓰레기로 간주하고 수거하는 기능을 함

          ex. class, interface, delegate, object, string

public class CallByRef {
	
	public static void increase(int[] array) {
		/* 배열을 매개변수로 받아서, 원래 저장된 값보다 1이 증가한 값으로 업데이트 */
		for(int i = 0; i < array.length; i++) {
			array[i]++;
		}
	}

	public static void main(String[] args) {
		int[] refArray = {100, 800, 1000}; // 배열 선언 및 초기화. 배열은 참조형 데이터
		
	    System.out.println("메서드 호출 전");
	    for(int i = 0; i < refArray.length; i++) {
	    	System.out.println("refArray[" + i + "]: " + refArray[i]);
	    }
	    
	    increase(refArray); // 리턴이 없음.
	    
	    System.out.println();
	    System.out.println("메서드 호출 후");
	    // 배열은 참조형이라 메서드 호출 후 값이 변경.
	    for(int i = 0; i < refArray.length; i++) {
	    	System.out.println("refArray[" + i + "]: " + refArray[i]);
	    }
	}
}

 

 

  C.  문자열에 의한 호출

  • 예외적으로 문자열을 전달하려면 참조형 데이터라도 값에 의한 호출을 함. 값에 의한 호출이기 때문에 값을 변경할려면 변경된 문자열을 리턴하고 호출한 쪽에서 값을 저장하면 됨
public class CallByString {

    public static String setAddress(String addr) {
    	addr = "경기도 수원시 장안구";
    	return addr;
    }
	
	public static void main(String[] args) {
	    String address = " 서울시 강남구 논현동";
	    
	    System.out.println("메서드 호출 전");
	    System.out.println("address: " + address); // address: 서울시 강남구 논현동
	    
	    address = setAddress(address);
	    
	    System.out.println("메서드 호출 후");
	    System.out.println("address: " + address); // address: 경기도 수원시 장안구
		
	}
}

 

 값 복사  VS  참조 복사
public class MyMethod_04 {

	public static void main(String[] args) {
		/* 깊은 복사. 값 복사. 기본형 변수
		 * deep copy
		 * 데이터 자체가 복사된다.
		 * 복사된 두 객체는 완전히 독립적인 메모리를 차지.
		 */
		int a = 1;
		int b = a;
		b++;
		
		System.out.println("a: " + a + ", b: " + b); // a: 1, b: 2
		
		/* 얕은 복사. 참조 복사. 참조형 변수
		 * shallow copy
		 * 값 자체를 복사하는 것이 아니라 주소값을 복사하여 같은 메모리를 가리키기 때문.
		 */
		int[] nums_01 = new int[1];
		nums_01[0] = 1;
		
		int[] nums_02 = nums_01;
		nums_02[0] = 2;
		
		System.out.println("nums_01[0]: " + nums_01[0] + ", nums_02[0]:" + nums_02[0]);
		// nums_01[0]: 2, nums_02[0]:2

	}
}
 
 

5)  return 문

  • 현재 실행중인 메서드를 종료하고 호출한 메서드로 되돌아간다.
  • 반환타입이 void 인 경우, return문 없어도 문제가 되지 않는다  ➡️  컴파일러가 메서드의 마지막에 자동적으로 추가해주기 때문
  • 결과로 사용되는 유형 : void, 기본자료형, 클래스형 등
public class ExMethod {

	public void print() {
	    System.out.println("메서드를 호출한다");
	    // 리턴 타입이 없더라도 return을 사용할 수 있음.
	    // 다만 return 다음에 값이 없어야 함.
	    // return의 의미는 이 부분에서 메서드 실행을 종료하고 복귀한다는 의미.
	    // return;
	}
	
	public static void main(String[] args) {
    
	    // 사용할 메서드가 있는 클래스의 인스턴스 선언
		ExMethod method = new ExMethod();
		method.print();
		method.print();
		method.print();

	}
}



 
반환값(return value)
int add(int x, int y) { 
    int result = x + y; 
    return x+y;
}

  -  반환값으로 주로 변수가 오긴 하지만 위의 코드처럼 'x+y' 수식이 올 수 있다. (수식의 결과가 반환됨)

  -  간단한 메서드의 경우 if문 대신 조건연산자(ex. 삼항연산자)를 사용하기도 함.

 

매개변수의 유효성 검사

 

  -  메서드의 구현부{}를 작성할 때, 제일 먼저 해야 하는 일이 매개변수의 값이 적절한 것인지 확인하는 것

       ➡️  타입만 맞으면 어떤 값도 매개변수를 통해 넘어올 수 있기 때문.

  -  적절하지 않은 값이 매개변수를 통해 넘어온다면 매개변수의 값을 보정하던가, 보정하는 것이 불가능하다면 return문을 사용해서 작업을 중단하고 호출한 메서드로 되돌아가야 한다.


예제 문제

 

  📍 밑변이 30, 높이가 10인 사각형의 넓이를 출력하세요
        * 단 메서드 calculator()를 호출해서 출력하세요

public class Ex_01_01 {
	public static void main(String[] args) {
		
		int width = 30;
		int height = 10;
		System.out.println("밑변이 "+ width + " 높이가 " + height + "인 사각형의 넓이는 " + calculator(width,height) + "입니다.");
	
    }
	
	static int calculator(int a, int b) {
    	System.out.println("계산을 시작합니다.");
        int area = a * b; // 밑변 * 높이 = 사각형의 높이
        return area;
	}
}

 

직각 삼각형 만들기 
 
public class Ex_01_02 {
	/* 
	 * 별이 출력되는 부분은 putStars() 메서드를 정의해서 구현하세요.
	 * 몇 단 : 4
	 * *
	 * **
	 * ***
	 * ****
	 */
     
	static void putStars(int limit) {
	    for( int i = 1; i <= limit; i++) {
	    	System.out.print("*");
	    }
	}
	
	public static void main(String[] args) {
	     Scanner scanner = new Scanner(System.in);
	    
	     System.out.println("좌하변이 직각인 직각삼각형을 표시합니다.");
	     System.out.print("몇 단 : ");
	     int n = scanner.nextInt();
	     
	     for(int i = 1; i <= n; i++) {
	    	 //putStars() 메서드 호출
	    	 putStars(i);
	    	 System.out.println();
	     }
	     scanner.close();
	}
}
 
 
 


6)  메서드 종류

매개변수, 반환 값 모두 있는 경우
int method(int a) { int b; return b; }

 

매개변수는 있는데, 반환 값이 없는 경우
void method(int a) { }

 

 

매개변수는 없는데, 반환 값이 있는 경우

 

int method() { int b; return b; }

 

 
매개변수, 반환 값 모두 없는 경우
void method() { }

 

 

 

 

 

 

* 내용 참고 : 학원강의 및 자바의정석 3rd


 

1.  배열의 활용 

1) 섞기 (shuffle)  -  배열의 요소의 순서를 바꾼다 (ex. 카드섞기, 로또번호생성)

 

  1)  길이가 10인 배열을 생성, 0~9의 숫자로 차례대로 초기화하여 출력

  2)  random()을 이용해서 배열의 임의의 위치에 있는 값과 배열의 첫 번째 요소인 number[0]의 값을 교환하는 일을 반복

        ❗️ number[0]과 number[n]에 저장된 값을 서로 바꾸려면 별도의 저장공간이 하나 더 필요

 

// 별도 공간 생성 방법
int tmp = number [0];
number [0] = number [n];
nuber [n] = tmp;

 

public class MyArray_05 {

	public static void main(String[] args) {
		int[] number = new int[10];
		
		for(int i = 0; i < number.length; i++) {
			number[i] = i; // 배열을 0 ~ 9의 숫자로 초기화한다.
		    System.out.print(number[i] + " "); // 0 1 2 3 4 5 6 7 8 9
		}
		System.out.println();
		
		for(int i = 0; i < 10000; i++) {
			int n = (int)(Math.random() * 10); // 0~9중의 한 값을 임의로 얻는다.
			
			// swap
			int temp = number[0];
			number[0] = number[n];
			number[n] = temp;
		}

		for (int i = 0; i < number.length; i++) {
			System.out.print(number[i] + " ");  // 2 4 8 7 6 0 5 9 1 3 
		}
	}
}
 
로또번호 생성하기 

 

  1)  길이가 45인 배열에 1부터 45까지의 값을 담는다

  2)  반복문을 이용해서 배열의 인덱스가 i인 값과 random()에 의해서 결정된 임의의 위치에 있는 값과 자리를 바꾸는 것을 6번 반복한다.

       ❗️임의의 값으로 배열 채우기

public class MyArray_05_01 {

	public static void main(String[] args) {
		int[] number = new int[45];
		
		for(int i = 0; i < number.length; i++) {
			number[i] = i+1; 
		    System.out.print(number[i] + " "); 
		}
	    
        System.out.println();
	    for(int i =0; i < 10000; i++) {
	    	int n = (int)(Math.random() * 45);
	    	
	    	// swap
	    	int temp = number[0];
	    	number[0] = number[n];
	    	number[n] = temp;
	    }

	    for (int i = 0; i < 6; i++) {
	    	System.out.print(number[i] + " ");
	    }
	}
}

로또 중복값 제거
public class Ex_01_Array_04 {

	public static void main(String[] args) {

		int[] numbers = new int[6];
        
		for(int i = 0; i < numbers.length; i++) {
			int temp = (int)(Math.random() * 45) + 1; // 1 ~ 45의 임의의 값을 얻는다.
			
			// 기존에 값이 있는지 확인
			boolean isResult = true; 
			for(int j = 0; j < i; j++) {
            
			    if (numbers[j] == temp) {
				    System.out.println(temp + "은 중복된 값입니다.");
				    isResult = false;
				    break;
				}
			} 
			
			// 중복이 없으면 저장, 중복이 있으면 i값 1감소
			if (isResult) {
				numbers[i] = temp;
			}
			else {
				i--;
			}
		}
        System.out.println(Arrays.toString(numbers));
	}
}
 
 

2.  2차원 배열

타입[][] 배열이름 ;
ex. int [][] scores = new int [3] [3] ;

 

🚀  2차원 배열의 선언 방법은 1차원 배열을 선언하는 부분에 괄호[]를 하나 더 추가

🚀  2차원 배열은 행과 열로 구성되어 있으며 첫 번째 괄호의 인덱스가 행을, 두 번째 괄호의 인덱스가 열을 뜻함

       ➡️ 위의 예제를 풀어보면 3행 3열을 뜻함. (3x3 = 총 9개의 방이 생김)

🚀  배열을 순회하려면 for문이 2개 필요

 

public class MyArray_07 {

	public static void main(String[] args) {
		/* 2차원 배열 선언 및 출력 */
	    int[][] arr = {
	    		{1, 2, 3}, 
	    		{4, 5, 6}
	    }; // 2차원 배열 선언
		
		for(int i = 0; i < arr.length; i++) {
			for(int j = 0; j < arr[i].length; j++) {
				System.out.print(arr[i][j] + " ");			
				}
			System.out.println();
		}
		
		System.out.println("행: " + arr.length); // 2 (길이는 행만 불러옴)
		System.out.println("열: " + arr[0].length); // 3 (0행의 칸이 몇개인지를 불러옴)

	}

}

 

 

응용 문제

 

  📍 중첩 for문을 이용해서 주어진 배열의 전체 항목의 합과 평균값을 구하세요

public class Ex_02_02 {

	public static void main(String[] args) {

		int[][] array = {
                {95, 86},
                {83, 92, 96},
                {78, 83, 93, 87, 88}
        };
		
		int sum = 0;
		double avg = 0.0;
		int count = 0;
		
		for(int i = 0; i < array.length; i++) {
			for(int j = 0; j < array[i].length; j++) {
				sum += array[i][j];
				count++;
			}
		}
		avg = (double) sum / count;
		
		System.out.println("sum: " + sum); // 881
		System.out.println("avg: " + avg); // 88.1
	}
}

 

 

 

 

* 내용참고 - 수업 강의 및 자바의 정석

 


배열 (Array)

💡 같은 타입여러 변수를 하나의 묶음으로 다루는 것

💡 String[] classGroup = { "김철수", "김영희", "한소희",...}

       ➡️  classGroup이라는 변수에 문자열로 된 배열이 담긴다.

 

1)  배열의 선언과 생성

선언방법 선언 예
타입[] 변수이름; int[] score;
String[] name;
타입 변수이름[]; int score[];
String name[];

 

a.  배열의 생성

타입[] 변수이름;                         //  배열을 선언 (배열을 다루기 위한 참조변수 선언)
변수이름 = new 타입[길이];    //  배열을 생성 (실제 저장공간을 생성)

 

  📍  각 배열요소는 자동적으로 int의 기본값(default)인 0으로 초기화

 


 2)  배열의 길이와 인덱스

 

  🚀  생성된 배열의 각 저장공간을 '배열의 요소(element)'라고 하며, '배열이름[인덱스]'의 형식으로 배열의 요소에 접근한다.

  🚀  인덱스(index)는 배열의 요소마다 붙여진 일련번호

         ➡️  인덱스의 범위는 0부터 '배열길이 -1'까지

         ➡️  인덱스로 상수 대신 변수나 수식도 사용할 수 있다

​score[0] = 0 ;
score[1] = 10;
score[2] = 20;
score[3] = 30;
score[4] = 40;

​* [0],[1],[2],[3],..  : '인덱스'(위치를 알려주는 원리)
for (int i = 0; i < 5; i++) {
    score[i] = i * 10;
}

 

a.  배열의 길이

    · 배열의 길이는 양의 정수(0도 포함) 이어야 하며 최대값은 int 타입의 최대값, 약 20억이다

 

b.  배열이름.length

    ·  배열은 한번 생성하면 길이를 변경할 수 없기 때문에, 이미 생성된 배열의 길이는 변하지 않는다.

    ·  '배열이름.length'는 상수다.

    ·  for문의 조건식에 배열의 길이를 직접 적어주는 것보다. '배열이름.length'를 사용하는 것이 좋다.

 

c.  배열의 길이 변경하기

 

  1) 더 큰 배열을 새로 생성

  2) 기존 배열의 내용을 새로운 배열에 복사

 

 

3)  배열의 초기화

  🚀  배열은 생성과 동시에 자동적으로 기본값으로 초기화 됨

         ➡️  원하는 값을 저장하려면 각 요소마다 값을 지정해줘야 함

         ➡️  배열의 길이가 큰 경우에는 요소 하나하나에 값을 지정하기 보다는 for문을 사용

int score = new int [] { a , b, c, d, e };    //  배열의 생성과 초기화를 동시에
int score = { a , b, c, d, e };                        //  new int[] 를 생략할 수 있음
 (단, 배열의 선언과 생성을 따로하는 경우에는 생략 불가)
 
int[] score = new int[0];     // 길이가 0인 배열
int[] score = new int[]{};    // 길이가 0인 배열
int[] score = {};             // 길이가 0인 배열, new int [ ] 가 생략됨

 


4)  배열의 출력

  🚀  for문 사용 또는 Arrays.toString(배열이름) 메서드 사용

          → 배열의 모든 요소를 '[첫번째 요소, 두번째 요소, ...]' 와 같은 형식의 문자열로 만들어서 반환

  🚀  아래 변수 iArr 값을 바로 출력하면 '타입 @ 주소' 형식으로 출력된다.

        참조변수는 heap 영역에, 지역변수&매개변수는 stack 영역에 저장 됨.

-> 그렇기 때문에 참조 변수는 주소로 출력됨.

int[] iArr = {100, 95, 80, 70, 60}; 

for(int i = 0; i < iArr.length; i++) {
    System.out.println(iArr[i] + ","); 
}

System.out.println();  
System.out.prinln(iArr); // [I@7344699f
System.out.prinln(Arrays.toString(iArr)); // [100, 95, 80, 70, 60]

 


  ✓  메모리 구조

 

☕ 그림으로 보는 자바 코드의 메모리 영역(스택 & 힙)

자바의 메모리 영역 이번 포스팅에선 자바(JAVA)를 사용하는 입장에서 알아야 할 메모리 구조 및 특징에 대해서 알아보려고 한다. 자바 프로그램이 실행되면 JVM(자바 가상 머신)은 OS로부터 메모

inpa.tistory.com

 


 

public class Exam01 {

	public static void main(String[] args) {
		
		int[] student; // 힙공간의 배열의 주소가 저장될 변수 생성.
		student = new int[3]; // 힙공간의 길이가 3인 배열 생성(연속된 주소를 가짐)하고 주소를 반환.

		// 정수 배열이 생성이 되고, 초기화를 하지 않으면 자동으로 0으로 초기화.
		System.out.println("현재 자동으로 초기화된 값: " + student[0]); // 0

		// 인덱스를 이용하여 개별 요소의 값을 변경.
		student[0] = 30; // 배열의 첫 번째 요소에 30을 저장
		student[1] = 20; // 배열의 두 번째 요소에 20을 저장
	    student[2] = 10; // 배열의 세 번째 요소에 10을 저장
	    
	    System.out.println("현재 첫 번째 요소의 값: " + student[0]); // 30
	}
}

배열 출력 3가지 방법

 

  📍  for문 출력  |  foreach문 출력  |  Array.toString() 출력 

public class Exam02 {

	public static void main(String[] args) {
    
		// for문으로 배열 초기화
		int[] c = new int[10];
		for(int i = 0; i < c.length; i++) {
			c[i] = i;
		}
		
		// 배열의 요소를 출력하는 방법 3가지.
		// for문을 이용한 출력
		System.out.println(c.length);
		for (int i = 0; i < c.length; i++) {
			System.out.println(c[i]);
		}
		
		// foreach 문을 이용한 출력
		System.out.println();
		for(int d: c) { // (배열의 요소 : 배열).
			// 반복시에 변수 d에 순서대로 요소가 들어감. 자바스크립트의 for of문과 유사.
			System.out.println(d);
		}
		
		// Arrays.toString 메서드 사용. 문자열로 출력.
	    System.out.println();
	    System.out.println(Arrays.toString(c));

	}
}

 

 
 
 
배열 사용 X  VS. 배열 사용 O

  ✔️  학생 5명의 성적 총점과 평균

public class MyArray_01 {

	public static void main(String[] args) {
	
		// 1. 배열을 사용하지 않는 경우
	    int score_001 = 95;
	    int score_002 = 76;
	    int score_003 = 67;
	    int score_004 = 56;
	    int score_005 = 87;
	    
	    int total = score_001 + score_002 + score_003 + score_004 + score_005;
	    double avg = (double)total / 5;
	    System.out.println("총점은 " + total + "점이고, 평균은 " + avg + "입니다.");
	    
	    // 2. 배열을 사용하는 경우
	    // 총점은 for문을 이용해서 구할 수 있고, 배열의 갯수가 늘어난다 해도
	    // 총점을 구하는 for문과 평균을 구하는 코드를 수정할 필요가 없음
	    total = 0;
	    int[] scores = {95, 76, 67, 56, 87}; // 배열 생성
	    for (int i = 0; i < scores.length; i++) {// scores.length -> 배열의 갯수
	    	total += scores[i];
	    	
	    }
	    avg = (double)total / scores.length;
	    System.out.println("총점은 " + total + "점이고, 평균은 " + avg + "입니다.");
	}
}

 

최대값 최소값 구하기
public class MyArray_03 {

	public static void main(String[] args) {
		/* 최대값, 최소값 구하기 */
		int[] score = { 79, 88, 91, 33, 100, 55, 95 };
		
		int max = score[0]; // 배열의 첫 번째 값으로 최대값을 초기화 한다.
		int min = score[0]; // 배열의 첫 번째 값으로 최소값을 초기화 한다.
		
		for(int i = 1; i < score.length; i++) {
			if(score[i] > max) {
				max = score[i];
			    System.out.println("max: " + max); // 값이 변경되는 것이 안 보이기 때문에 이해가 안될 때 써보기.
			}
			if(score[i] < min) {
				min = score[i];
			}
		} // end of for
		
		System.out.println("최대값 : " + max);
	    System.out.println("최소값 : " + min);

	}
}
 
 

 

​응용 문제
  📍 학생 수와 각 학생들의 점수를 입력받아서, 최고 점수 및 평균 점수를 구하는 프로그램
public class Ex_01_Array_03 {

	public static void main(String[] args) {
		
        Scanner scanner = new Scanner(System.in);
		
        boolean run = true;  // 반복문의 조건으로 사용 -> 값이 false가 된다면 반복문이 종료
        int studentNum = 0;  // 학생수
        int[] scores = null; // 점수를 입력 받을 빈 배열 생성. 사용자에게 입력받은 학생수를 기준으로 배열 생성.
        
        
        while (run) {
        
            System.out.println("-----------------------------------------------------");
            System.out.println("1.학생수 | 2.점수입력 | 3.점수리스트 | 4.분석 | 5.종료");
            System.out.println("-----------------------------------------------------");
            System.out.print("선택> ");
           
            int selectNo = scanner.nextInt();
          
            if (selectNo == 1) { // 학생수를 입력 받아서 배열 생성 
     
                System.out.print("학생수> ");
                studentNum = scanner.nextInt();
                scores = new int[studentNum];
                
                System.out.println(Arrays.toString(scores));
                
            } else if (selectNo == 2) { // 생성된 배열의 갯수 만큼 점수 입력
            	
                for(int i = 0; i < scores.length; i++) {
                	System.out.print("scores["+i+"] : ");
                	scores[i] = scanner.nextInt();
                }
            	
            } else if (selectNo == 3) { // 입력받은 배열의 값을 출력

            	for(int i = 0; i < scores.length; i++) {
                    System.out.println("score["+i+"] : " + scores[i]);
            	}
            	
            } else if (selectNo == 4) { // 최고 점수, 평균 점수 출력
                
            	int max = 0;
            	int sum = 0;
            	double avg = 0;
            	
            	for(int i = 0; i < scores.length; i++) {
            		max = (max < scores[i]) ? scores[i] : max;
            		sum += scores[i];
        		}
                
        		avg = (double) sum / studentNum; // 평균
        		System.out.println("최고 점수: " + max);
            	System.out.println("평균 점수: " + avg);
            	
            } else if (selectNo == 5) { // run 값 변경
                run = false;
            }
        }
        System.out.println("프로그램 종료");
        scanner.close();
    }
}
 
 실행 예)
        -----------------------------------------------------
        1.학생수 | 2.점수입력 | 3.점수리스트 | 4.분석 | 5.종료
        -----------------------------------------------------
        선택> 1
        학생수> 3
        [0, 0, 0]
        -----------------------------------------------------
        1.학생수 | 2.점수입력 | 3.점수리스트 | 4.분석 | 5.종료
        -----------------------------------------------------
        선택> 2
        scores[0]> 90
        scores[1]> 80
        scores[2]> 70
        -----------------------------------------------------
        1.학생수 | 2.점수입력 | 3.점수리스트 | 4.분석 | 5.종료
        -----------------------------------------------------
        선택> 3
        scores[0]: 90
        scores[1]: 80
        scores[2]: 70
        -----------------------------------------------------
        1.학생수 | 2.점수입력 | 3.점수리스트 | 4.분석 | 5.종료
        -----------------------------------------------------
        선택> 4
        최고 점수: 90
        평균 점수: 80.0
        -----------------------------------------------------
        1.학생수 | 2.점수입력 | 3.점수리스트 | 4.분석 | 5.종료
        -----------------------------------------------------
        선택> 5
        프로그램 종료

 

 
 
 

 

* 내용 참고 : 학원강의 및 자바의 정석 3rd

 

 


1.  while 문

int i=1; // 초기화
while (조건식) {
    // 조건식이 연산결과가 참인 동안, 반복될 문장들을 적는다.
    System.out.println(i);
    i++; // 증감식
}

💡  먼저 조건식을 평가해서 조건식이 거짓이면 문장 전체를 벗어나고, 참이면 블럭 {} 내의 문장을 수행하고 다시 조건식으로 돌아간다.

        ➡️  조건식이 거짓이 될 때까지 이 과정이 계속 반복

💡 조건식에는 비교 또는 논리 연산식이 주로 옴

💡  for문과 while문은 항상 서로 변환이 가능. 단, for문과 달리 조건식 생략 불가!

public class MyWhile_02 {

	public static void main(String[] args) {
		/* for문을 while문으로 변경 */
		
		int num;
		int sum = 0;
		
		for (num=1; num <= 10; num++) {
			sum += num;
		}
		System.out.println("1부터 10까지의 합은 " + sum + "입니다.");
		
		// While문도 초기값, 조건식, 증감식이 존재.
		num = 1;
		sum = 0;
		while(num <= 10) {
			sum += num;
			num++;
		}
	    System.out.println("1부터 10까지의 합은 " + sum + "입니다.");

	}

}

 

 중첩 while문
public class MyWhile_11 {

	public static void main(String[] args) {
		/* 중첩 while, 구구단 출력 */
		int i = 2;
		while(i <= 9) {
			System.out.println("*** " + i + "단 ***");
			int j = 1;
			while(j <= 9) {
				System.out.println(i +" * "+j+" = " + i*j);
				j++;
			}
			System.out.println();
			i++;
		} // end of while(i<=9)

	}
}
 
 
응용 문제
public class Exam022 {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		String answer = "Y"; // while이 시작될 수 있도록 응답 값을 초기화.
		int count = 0;
		
		while (answer.equals("Y")|| answer.equals("y")) {
			System.out.println("음악을 재생하시겠습니까?(Y or y)");
			answer = scanner.nextLine(); // 사용자의 응답을 받습니다.
		    answer = answer.toUpperCase(); // 입력받은 문자열을 대문자로 변경.
			
			if (answer.equals("Y") || answer.equals("y")) {
				count++;
				System.out.println("음악을 "+count+"번 재생했습니다.");
				
			}		    
		}
	    System.out.println("재생종료");
	    scanner.close();
	}
}
 

 


2.  do-while 문

💡  while문의 변형으로 기본적인 구조는 while문과 같으나 조건식과 블럭{}의 순서를 바꿔놓은 것

       ➡️  블럭{}을 먼저 수행한 후에 조건식을 평가

       ➡️  while문은 조건식의 결과에 따라 블럭{}이 한 번도 수행되지 않을 수 있지만, do-while문은 최소한 한번은 수행될 것을 보장한다.

💡  실무에서 잘 사용하지는 않음

do {
  // 조건식의 연산결과가 참일 때 수행될 문장들을 적는다.
} while (조건식);
public class Exam023 {

	public static void main(String[] args) {
		/* do~while문은 조건이 거짓이라도 적어도 한번은 문장이 출력된다. */
		int num = 100;
		do {
			System.out.println("적어도 한번은 출력되는 문장");
		} while(num < 10);

	}
}
 
 
 
응용 문제
public class Ex_03_dowhile_01 {

	public static void main(String[] args) {
		/* do while 문을 사용해서 사용자로 부터 월의 번호를 입력받는 프로그램을 작성해 보세요.
		 * 사용자가 올바른 월 번호를 입력할 때 까지 반복을 계속합니다.
		 * 사용자가 올바른 월 번호를 입력해야만 다음 문장으로 넘어갑니다. */
		Scanner scanner = new Scanner(System.in);
		int month;
		
		do {
			System.out.print("올바른 월을 입력하세요 [1-12] ");
		    month = scanner.nextInt();
		} while (month < 1 || month > 12);
		
        System.out.println("사용자가 입력한 월은 " + month + "입니다.");
		scanner.close();

	}
}
 

📄   Random random = new Random();

  -  Random 클래스의 인스턴스를 생성하여 random이라는 변수에 저장하는 코드

  -  Random : Java에서 무작위 숫자를 생성하기 위한 클래스로, java.util 패키지에 포함되어 있다. 이 클래스는 난수를 생성하는 다양한 메서드를 제공함.

​ random() 메소드는 0.0과 1.0 사이의 double 타입 난수를 리턴

⚡️  0.0 <= Math.random() < 1.0

💡  start 부터 시작하는 n개의 정수 중에서 하나의 정수를 얻기 위한 코드
      int num = (int) (Math.random() * n) + start;

 

public class Ex_03_while_01_pr {

	public static void main(String[] args) {
		/* while 문과 Random.nextInt() 메소드를 이용해서 2개의 주사위를 던졌을 때 나오는 눈을 (눈1,눈2)
		 * 형태로 출력하고, 눈의 합이 5가 되는 조합은 (1,4) (4,1) (2,3) (3,2) 입니다.
		 * 예) (5,1)
		 * (4,4)
		 * (6,5)
		 * (5,2)
		 * (3,6)
		 * (1,2)
		 * (2,3)
		 */
		
		Random random = new Random();
		
		while(true) {
			int num1 = random.nextInt(6) + 1; 
			int num2 = random.nextInt(6) + 1;
			System.out.println("(" + num1 + ", " + num2 + ")");
		
			if ((num1+num2) == 5) {
				break;
			}
		}
	}
}

 

 

응용 문제
public class Ex_03_while_02 {

	public static void main(String[] args) {
		/* 컴퓨터가 주사위를 던지면 사용자가 주사위의 숫자를 맞히는 프로그램을 완성하세요.
		   사용자가 맞힐 때까지 게임은 계속 됩니다. 
		   예) 
		   주사위 값은 얼마일까요? >>> 5 
		   오답입니다. 다시 시도하세요. 
		   주사위 값은 얼마일까요? >>> 1
		   1! 정답입니다. 
		   
		   1) break를 사용
		   2) break를 사용안하는 경우 */
		Scanner scanner = new Scanner(System.in);
		Random random = new Random();
		
		
		int answer = random.nextInt(6) + 1;
		// System.out.println(answer);
		
		while(true) {
        
			System.out.print("주사위 값은 얼마일까요? >>> ");
			int num  = scanner.nextInt();
			
			if (answer == num) {
				break;
			}
			
            System.out.println("오답입니다. 다시 시도하세요.");
		}
        
	    System.out.println(answer + "! 정답입니다.");
	    scanner.close();
	}
		
}
 
 
 

3.  break 문

💡 자신이 포함된 가장 가까운 반복문을 벗어난다. 주로 if문과 함께 사용되어 특정 조건을 만족하면 반복문을 벗어나도록 한다.

public class Exam024 {

	public static void main(String[] args) {
		/* 반복문을 빠져나오는 방법은 1) 조건식이 false가 되거나 2) break문이 실행.
		 * break문은 반복을 멈추게 함.
		 * 반복문이 진행되다가 break문을 만나면 곧 바로 반복문을 벗어나서 반복문 다음의 코드를 수행. */
		Scanner scanner = new Scanner(System.in);
		int sum = 0;
		int num;
		
		while(true) {
			System.out.println("더할 숫자를 입력하세요:(종료하려면 0입력)");
			num = scanner.nextInt(); //정수 입력받아서 num에 저장
            
			if (num == 0) { // 만약 0을 입력하였다면 종료.
				break;
			}
            
			sum += num; //입력받은 값 더해주기.
		}
		System.out.println("현재까지의 총합 = " + sum);
        scanner.close();
	}
}

 

 


 

4.  continue 문

💡 반복문 내에서만 사용될 수 있으며, 반복이 진행되는 도중에 continue문을 만나면 반복문의 끝으로 이동하여 다음 반복으로 넘어간다.

 

  🔅  break 문  ➡️  반복을 종료, 실행 후 코드 아래의 반복문 코드는 실행되지 않음

  🔅  continue 문  ➡️  다음 반복으로 이동, 실행 후 코드 아래의 반복문 코드는 실행되지 않음

 

public class MyContinue_01 {

	public static void main(String[] args) {
		/* 
		  continue문은 현재의 반복을 뛰어넘고 다음 반복을 진행.
		  반복문이 진행되다가 continue문을 만나면 반복문의 제일 끝으로 가서 다음 반복을 계속 수행.
          0 ~ 100까지의 홀수만 더 함 
        */
        
		int total = 0;
		int num;
		
		for(num=0; num<=100; num++) {
        
			if(num%2 == 0) {
				continue;
			}
			
			total += num;
			
		}
        
		System.out.println("1부터 100까지의 홀수의 합은 " + total + "입니다.");
	}
}

 

 

응용 문제
public class Exam025_01 {

	public static void main(String[] args) {
		/* 한번에 출금할 수 있는 금액은 1000원 이하, break 사용하지 말것 */
		// break 사용하지 않는 방법 -> while의 조건식을 이용해서 반복문은 빠져 나올것.
		// -> 조건식에 뭘 써야 하나? -> break의 if 조건식은 반복을 종료하는 조건.
		// -> while의 조건식은?
		
	    Scanner scanner = new Scanner(System.in); 
		
		int money = 10000;

		System.out.println("현재 가진 돈은 " + money + "원 입니다.");
		
		while(money > 0) {
			System.out.print("얼마를 사용하시겠습니까? >>> ");
			int spendMoney = scanner.nextInt(); // 정수를 입력받음.
			
			if(spendMoney <= 0 || spendMoney > money) {
				System.out.println("다시 입력해 주세요(사용범위가 틀렸습니다.)");
				continue; // 현재의 반복을 벗어나서 다시 반복을 시작
			} else if (spendMoney > 1000) {
				System.out.println("1000원 이상은 출금할 수 없습니다.");
				continue;
			}
			
		    money -= spendMoney;
		    System.out.println("이제 " + money + "원이 남았습니다.");
		    
		}
		System.out.println("모든 돈을 사용합니다. 종료");
	    scanner.close();
	}
}

 

 

 

 

 

[ 출처 ; 학원 강의 및 자바의 정석 책 ]

+ Recent posts